DEV Community

Shivam Tyagi
Shivam Tyagi

Posted on

Uses of @spy annotation in junit testing

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:

  1. 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());
     }
    
  2. 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());
     }
    
  3. 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();
     }
    
  4. 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());
     }
    
  5. 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)