/* | |
* 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; | |
/** | |
* 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 spyOnFoo = Mockito.spy(new Bar()); | |
* </code></pre> | |
* | |
* <p> | |
* <strong>The field annotated with @Spy can be initialized by Mockito if a zero argument constructor | |
* can be found in the type (even private). <u>But Mockito cannot instantiate inner classes, local classes, | |
* abstract classes and interfaces.</u></strong> | |
* | |
* <strong>The 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 org.mockito.runners.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 org.mockito.runners.MockitoJUnitRunner | |
* @since 1.8.3 | |
*/ | |
@Retention(RUNTIME) | |
@Target(FIELD) | |
@Documented | |
public @interface Spy { } |