001/*
002 * Copyright 2012-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.test.mock.mockito;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Repeatable;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.lang.annotation.Target;
025
026import org.junit.runner.RunWith;
027import org.mockito.Answers;
028import org.mockito.MockSettings;
029
030import org.springframework.context.ApplicationContext;
031import org.springframework.core.annotation.AliasFor;
032import org.springframework.test.context.junit4.SpringRunner;
033
034/**
035 * Annotation that can be used to add mocks to a Spring {@link ApplicationContext}. Can be
036 * used as a class level annotation or on fields in either {@code @Configuration} classes,
037 * or test classes that are {@link RunWith @RunWith} the {@link SpringRunner}.
038 * <p>
039 * Mocks can be registered by type or by {@link #name() bean name}. Any existing single
040 * bean of the same type defined in the context will be replaced by the mock. If no
041 * existing bean is defined a new one will be added. Dependencies that are known to the
042 * application context but are not beans (such as those
043 * {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object)
044 * registered directly}) will not be found and a mocked bean will be added to the context
045 * alongside the existing dependency.
046 * <p>
047 * When {@code @MockBean} is used on a field, as well as being registered in the
048 * application context, the mock will also be injected into the field. Typical usage might
049 * be: <pre class="code">
050 * &#064;RunWith(SpringRunner.class)
051 * public class ExampleTests {
052 *
053 *     &#064;MockBean
054 *     private ExampleService service;
055 *
056 *     &#064;Autowired
057 *     private UserOfService userOfService;
058 *
059 *     &#064;Test
060 *     public void testUserOfService() {
061 *         given(this.service.greet()).willReturn("Hello");
062 *         String actual = this.userOfService.makeUse();
063 *         assertEquals("Was: Hello", actual);
064 *     }
065 *
066 *     &#064;Configuration
067 *     &#064;Import(UserOfService.class) // A &#064;Component injected with ExampleService
068 *     static class Config {
069 *     }
070 *
071 *
072 * }
073 * </pre> If there is more than one bean of the requested type, qualifier metadata must be
074 * specified at field level: <pre class="code">
075 * &#064;RunWith(SpringRunner.class)
076 * public class ExampleTests {
077 *
078 *     &#064;MockBean
079 *     &#064;Qualifier("example")
080 *     private ExampleService service;
081 *
082 *     ...
083 * }
084 * </pre>
085 * <p>
086 * This annotation is {@code @Repeatable} and may be specified multiple times when working
087 * with Java 8 or contained within an {@link MockBeans @MockBeans} annotation.
088 *
089 * @author Phillip Webb
090 * @since 1.4.0
091 * @see MockitoPostProcessor
092 */
093@Target({ ElementType.TYPE, ElementType.FIELD })
094@Retention(RetentionPolicy.RUNTIME)
095@Documented
096@Repeatable(MockBeans.class)
097public @interface MockBean {
098
099        /**
100         * The name of the bean to register or replace. If not specified the name will either
101         * be generated or, if the mock replaces an existing bean, the existing name will be
102         * used.
103         * @return the name of the bean
104         */
105        String name() default "";
106
107        /**
108         * The classes to mock. This is an alias of {@link #classes()} which can be used for
109         * brevity if no other attributes are defined. See {@link #classes()} for details.
110         * @return the classes to mock
111         */
112        @AliasFor("classes")
113        Class<?>[] value() default {};
114
115        /**
116         * The classes to mock. Each class specified here will result in a mock being created
117         * and registered with the application context. Classes can be omitted when the
118         * annotation is used on a field.
119         * <p>
120         * When {@code @MockBean} also defines a {@code name} this attribute can only contain
121         * a single value.
122         * <p>
123         * If this is the only specified attribute consider using the {@code value} alias
124         * instead.
125         * @return the classes to mock
126         */
127        @AliasFor("value")
128        Class<?>[] classes() default {};
129
130        /**
131         * Any extra interfaces that should also be declared on the mock. See
132         * {@link MockSettings#extraInterfaces(Class...)} for details.
133         * @return any extra interfaces
134         */
135        Class<?>[] extraInterfaces() default {};
136
137        /**
138         * The {@link Answers} type to use on the mock.
139         * @return the answer type
140         */
141        Answers answer() default Answers.RETURNS_DEFAULTS;
142
143        /**
144         * If the generated mock is serializable. See {@link MockSettings#serializable()} for
145         * details.
146         * @return if the mock is serializable
147         */
148        boolean serializable() default false;
149
150        /**
151         * The reset mode to apply to the mock bean. The default is {@link MockReset#AFTER}
152         * meaning that mocks are automatically reset after each test method is invoked.
153         * @return the reset mode
154         */
155        MockReset reset() default MockReset.AFTER;
156
157}