/* * Copyright (c) 2007 Mockito contributors * This program is made available under the terms of the MIT License. */ package org.mockito; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.mockito.junit.MockitoJUnitRunner; /** * Allows shorthand wrapping of field instances in an spy object. * * <p> * Example: * * <pre class="code"><code class="java"> * public class Test{ * //Instance for spying is created by calling constructor explicitly: * @Spy Foo spyOnFoo = new Foo("argument"); * //Instance for spying is created by mockito via reflection (only default constructors supported): * @Spy Bar spyOnBar; * @Before * public void init(){ * MockitoAnnotations.initMocks(this); * } * ... * } * </code></pre> * <p> * Same as doing: * * <pre class="code"><code class="java"> * Foo spyOnFoo = Mockito.spy(new Foo("argument")); * Bar spyOnBar = Mockito.spy(new Bar()); * </code></pre> * * <p> * <strong>A field annotated with @Spy can be initialized explicitly at declaration point. * Alternatively, if you don't provide the instance Mockito will try to find zero argument constructor (even private) * and create an instance for you. * <u>But Mockito cannot instantiate inner classes, local classes, abstract classes and interfaces.</u></strong> * * For example this class can be instantiated by Mockito : * <pre class="code"><code class="java">public class Bar { * private Bar() {} * public Bar(String publicConstructorWithOneArg) {} * }</code></pre> * </p> * * <h4>Important gotcha on spying real objects!</h4> * <ol> * <li>Sometimes it's impossible or impractical to use {@link Mockito#when(Object)} for stubbing spies. * Therefore for spies it is recommended to always use <code>doReturn</code>|<code>Answer</code>|<code>Throw()</code>|<code>CallRealMethod</code> * family of methods for stubbing. Example: * * <pre class="code"><code class="java"> * List list = new LinkedList(); * List spy = spy(list); * * //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) * when(spy.get(0)).thenReturn("foo"); * * //You have to use doReturn() for stubbing * doReturn("foo").when(spy).get(0); * </code></pre> * </li> * * <li>Mockito <b>*does not*</b> delegate calls to the passed real instance, instead it actually creates a copy of it. * So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction * and their effect on real instance state. * The corollary is that when an <b>*unstubbed*</b> method is called <b>*on the spy*</b> but <b>*not on the real instance*</b>, * you won't see any effects on the real instance.</li> * * <li>Watch out for final methods. * Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + you try to stub a final method = trouble. * Also you won't be able to verify those method as well. * </li> * </ol> * * <p> * <strong>One last warning :</strong> if you call <code>MockitoAnnotations.initMocks(this)</code> in a * super class <strong>constructor</strong> then this will not work. It is because fields * in subclass are only instantiated after super class constructor has returned. * It's better to use @Before. * <strong>Instead</strong> you can also put initMocks() in your JUnit runner (@RunWith) or use the built-in * {@link MockitoJUnitRunner}. * </p> * * <p>Note that the spy won't have any annotations of the spied type, because CGLIB won't rewrite them. * It may troublesome for code that rely on the spy to have these annotations.</p> * * @see Mockito#spy(Object) * @see Mock * @see InjectMocks * @see MockitoAnnotations#initMocks(Object) * @see MockitoJUnitRunner * @since 1.8.3 */ @Retention(RUNTIME) @Target(FIELD) @Documented public @interface Spy { }