|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: REQUIRED | OPTIONAL | DETAIL: ELEMENT |
@Retention(value=RUNTIME) @Target(value=FIELD) @Documented public @interface Spy
Allows shorthand wrapping of field instances in an spy object.
Example:
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);
}
...
}
Same as doing:
Foo spyOnFoo = Mockito.spy(new Foo("argument"));
Bar spyOnFoo = Mockito.spy(new Bar());
The field annotated with @Spy can be initialized by Mockito if a zero argument constructor can be found in the type (even private). But Mockito cannot instantiate inner classes, local classes, abstract classes and interfaces. 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. But Mockito cannot instantiate inner classes, local classes, abstract classes and interfaces. For example this class can be instantiated by Mockito :
public class Bar {
private Bar() {}
public Bar(String publicConstructorWithOneArg) {}
}
Mockito.when(Object)
for stubbing spies.
Therefore for spies it is recommended to always use doReturn
|Answer
|Throw()
|CallRealMethod
family of methods for stubbing. Example:
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);
One last warning : if you call MockitoAnnotations.initMocks(this)
in a
super class constructor 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.
Instead you can also put initMocks() in your JUnit runner (@RunWith) or use the built-in
MockitoJUnitRunner
.
Mockito.spy(Object)
,
Mock
,
InjectMocks
,
MockitoAnnotations.initMocks(Object)
,
MockitoJUnitRunner
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: REQUIRED | OPTIONAL | DETAIL: ELEMENT |