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.Mockito;
028
029import org.springframework.context.ApplicationContext;
030import org.springframework.core.annotation.AliasFor;
031import org.springframework.test.context.junit4.SpringRunner;
032
033/**
034 * Annotation that can be used to apply Mockito spies to a Spring
035 * {@link ApplicationContext}. Can be used as a class level annotation or on fields in
036 * either {@code @Configuration} classes, or test classes that are
037 * {@link RunWith @RunWith} the {@link SpringRunner}.
038 * <p>
039 * Spies can be applied by type or by {@link #name() bean name}. All beans in the context
040 * of the same type will be wrapped with the spy. If no existing bean is defined a new one
041 * will be added. Dependencies that are known to the application context but are not beans
042 * (such as those
043 * {@link org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerResolvableDependency(Class, Object)
044 * registered directly}) will not be found and a spied bean will be added to the context
045 * alongside the existing dependency.
046 * <p>
047 * When {@code @SpyBean} is used on a field, as well as being registered in the
048 * application context, the spy 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;SpyBean
054 *     private ExampleService service;
055 *
056 *     &#064;Autowired
057 *     private UserOfService userOfService;
058 *
059 *     &#064;Test
060 *     public void testUserOfService() {
061 *         String actual = this.userOfService.makeUse();
062 *         assertEquals("Was: Hello", actual);
063 *         verify(this.service).greet();
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;SpyBean
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 a {@link SpyBeans @SpyBeans} 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(SpyBeans.class)
097public @interface SpyBean {
098
099        /**
100         * The name of the bean to spy. If not specified the name will either be generated or,
101         * if the spy is for an existing bean, the existing name will be used.
102         * @return the name of the bean
103         */
104        String name() default "";
105
106        /**
107         * The classes to spy. This is an alias of {@link #classes()} which can be used for
108         * brevity if no other attributes are defined. See {@link #classes()} for details.
109         * @return the classes to spy
110         */
111        @AliasFor("classes")
112        Class<?>[] value() default {};
113
114        /**
115         * The classes to spy. Each class specified here will result in a spy being applied.
116         * Classes can be omitted when the annotation is used on a field.
117         * <p>
118         * When {@code @SpyBean} also defines a {@code name} this attribute can only contain a
119         * single value.
120         * <p>
121         * If this is the only specified attribute consider using the {@code value} alias
122         * instead.
123         * @return the classes to spy
124         */
125        @AliasFor("value")
126        Class<?>[] classes() default {};
127
128        /**
129         * The reset mode to apply to the spied bean. The default is {@link MockReset#AFTER}
130         * meaning that spies are automatically reset after each test method is invoked.
131         * @return the reset mode
132         */
133        MockReset reset() default MockReset.AFTER;
134
135        /**
136         * Indicates that Mockito methods such as {@link Mockito#verify(Object) verify(mock)}
137         * should use the {@code target} of AOP advised beans, rather than the proxy itself.
138         * If set to {@code false} you may need to use the result of
139         * {@link org.springframework.test.util.AopTestUtils#getUltimateTargetObject(Object)
140         * AopTestUtils.getUltimateTargetObject(...)} when calling Mockito methods.
141         * @return {@code true} if the target of AOP advised beans is used or {@code false} if
142         * the proxy is used directly
143         */
144        boolean proxyTargetAware() default true;
145
146}