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 * @RunWith(SpringRunner.class) 051 * public class ExampleTests { 052 * 053 * @SpyBean 054 * private ExampleService service; 055 * 056 * @Autowired 057 * private UserOfService userOfService; 058 * 059 * @Test 060 * public void testUserOfService() { 061 * String actual = this.userOfService.makeUse(); 062 * assertEquals("Was: Hello", actual); 063 * verify(this.service).greet(); 064 * } 065 * 066 * @Configuration 067 * @Import(UserOfService.class) // A @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 * @RunWith(SpringRunner.class) 076 * public class ExampleTests { 077 * 078 * @SpyBean 079 * @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}