The @Spy
annotation in JUnit, particularly when used with Mockito, is applied to create a spy on an actual object. A spy is a partial mock, which means that you can mock some methods of the object while retaining the real behavior of other methods.
Here are some common uses of the @Spy
annotation:
-
Partial Mocking:
- If you have an object where most methods need to retain their actual behavior but one or two methods need to be mocked, you can use a spy.
- Example:
@Spy private List<String> spyList = new ArrayList<>(); @Test public void testSpy() { spyList.add("Mockito"); Mockito.verify(spyList).add("Mockito"); assertEquals(1, spyList.size()); Mockito.doReturn(100).when(spyList).size(); assertEquals(100, spyList.size()); }
-
Overriding Real Method Behavior:
- You can use a spy to override specific method behavior of a real object while keeping the rest of the methods intact.
- Example:
@Spy private MyClass myClass = new MyClass(); @Test public void testSpyWithMethodOverride() { Mockito.doReturn("Mocked Value").when(myClass).someMethod(); assertEquals("Mocked Value", myClass.someMethod()); }
-
Verifying Method Calls:
- You can verify if certain methods were called on the spy, which is helpful when testing interactions.
- Example:
@Spy private MyClass myClass = new MyClass(); @Test public void testMethodCallVerification() { myClass.someMethod(); Mockito.verify(myClass).someMethod(); }
-
Combining with
@InjectMocks
:-
@Spy
can be used in conjunction with@InjectMocks
to inject spied objects into the object being tested, allowing partial mocking within the tested class. - Example:
@Spy private MyDependency dependency; @InjectMocks private MyService service; @Test public void testService() { Mockito.doReturn("Mocked Result").when(dependency).doSomething(); assertEquals("Mocked Result", service.performAction()); }
-
-
Testing Legacy Code:
- When dealing with legacy code that you cannot easily refactor, using a spy allows you to isolate and mock specific methods without changing the original code.
In summary, the @Spy
annotation is useful when you need to control or verify specific behaviors of an actual object while keeping the rest of the object's behavior unchanged.
Top comments (0)