/* * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.test.mock.mockito; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AliasFor; import org.springframework.test.context.junit4.SpringRunner; /** * Annotation that can be used to apply Mockito spies to a Spring * {@link ApplicationContext}. Can be used as a class level annotation or on fields in * either {@code @Configuration} classes, or test classes that are * {@link RunWith @RunWith} the {@link SpringRunner}. * <p> * Spies can be applied by type or by {@link #name() bean name}. All beans in the context * of the same type will be wrapped with the spy. If no existing bean is defined a new one * will be added. * <p> * When {@code @SpyBean} is used on a field, as well as being registered in the * application context, the spy will also be injected into the field. Typical usage might * be: <pre class="code"> * @RunWith(SpringRunner.class) * public class ExampleTests { * * @SpyBean * private ExampleService service; * * @Autowired * private UserOfService userOfService; * * @Test * public void testUserOfService() { * String actual = this.userOfService.makeUse(); * assertEquals("Was: Hello", actual); * verify(this.service).greet(); * } * * @Configuration * @Import(UserOfService.class) // A @Component injected with ExampleService * static class Config { * } * * * } * </pre> If there is more than one bean of the requested type, qualifier metadata must be * specified at field level: <pre class="code"> * @RunWith(SpringRunner.class) * public class ExampleTests { * * @SpyBean * @Qualifier("example") * private ExampleService service; * * ... * } * </pre> * <p> * This annotation is {@code @Repeatable} and may be specified multiple times when working * with Java 8 or contained within a {@link SpyBeans @SpyBeans} annotation. * * @author Phillip Webb * @since 1.4.0 * @see MockitoPostProcessor */ @Target({ ElementType.TYPE, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(SpyBeans.class) public @interface SpyBean { /** * The name of the bean to spy. If not specified the name will either be generated or, * if the spy is for an existing bean, the existing name will be used. * @return the name of the bean */ String name() default ""; /** * The classes to spy. This is an alias of {@link #classes()} which can be used for * brevity if no other attributes are defined. See {@link #classes()} for details. * @return the classes to spy */ @AliasFor("classes") Class<?>[] value() default {}; /** * The classes to spy. Each class specified here will result in a spy being applied. * Classes can be omitted when the annotation is used on a field. * <p> * When {@code @SpyBean} also defines a {@code name} this attribute can only contain a * single value. * <p> * If this is the only specified attribute consider using the {@code value} alias * instead. * @return the classes to spy */ @AliasFor("value") Class<?>[] classes() default {}; /** * The reset mode to apply to the spied bean. The default is {@link MockReset#AFTER} * meaning that spies are automatically reset after each test method is invoked. * @return the reset mode */ MockReset reset() default MockReset.AFTER; /** * Indicates that Mockito methods such as {@link Mockito#verify(Object) verify(mock)} * should use the {@code target} of AOP advised beans, rather than the proxy itself. * If set to {@code false} you may need to use the result of * {@link org.springframework.test.util.AopTestUtils#getUltimateTargetObject(Object) * AopTestUtils.getUltimateTargetObject(...)} when calling Mockito methods. * @return {@code true} if the target of AOP advised beans is used or {@code false} if * the proxy is used directly */ boolean proxyTargetAware() default true; }