0
0
JunitHow-ToBeginner ยท 4 min read

How to Use Spy in Mockito with JUnit for Effective Testing

In JUnit tests, use Mockito.spy() to create a spy object that wraps a real instance, allowing you to call real methods while still verifying interactions or stubbing specific methods. This helps test partial behavior without fully mocking the object.
๐Ÿ“

Syntax

The spy method in Mockito creates a spy object from a real instance. You can then stub or verify methods on this spy.

  • spyObject = Mockito.spy(realObject); - creates a spy wrapping the real object.
  • Mockito.doReturn(value).when(spyObject).method(); - stubs a method on the spy.
  • Mockito.verify(spyObject).method(); - verifies method calls on the spy.
java
MyClass realObject = new MyClass();
MyClass spyObject = Mockito.spy(realObject);

Mockito.doReturn("stubbed").when(spyObject).someMethod();

spyObject.someMethod();

Mockito.verify(spyObject).someMethod();
๐Ÿ’ป

Example

This example shows how to spy on a list, stub one method, and verify method calls using JUnit and Mockito.

java
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

public class SpyExampleTest {

    @Test
    public void testSpyList() {
        List<String> realList = new ArrayList<>();
        List<String> spyList = spy(realList);

        // Stub size() method to return 100
        doReturn(100).when(spyList).size();

        // Add elements calls real methods
        spyList.add("one");
        spyList.add("two");

        // size() returns stubbed value
        assertEquals(100, spyList.size());

        // Verify add was called twice
        verify(spyList).add("one");
        verify(spyList).add("two");
    }
}
Output
Test passed successfully with all assertions and verifications met.
โš ๏ธ

Common Pitfalls

  • Calling real methods unintentionally: Spy calls real methods by default, so side effects can happen if not careful.
  • Stubbing with when(spy.method()): This can call the real method and cause issues; use doReturn().when(spy) instead.
  • Spying on null or final classes: Mockito cannot spy on null objects or final classes without additional configuration.
java
/* Wrong way - calls real method during stubbing, may cause side effects */
// when(spyList.size()).thenReturn(100); 

/* Right way - avoids calling real method during stubbing */
doReturn(100).when(spyList).size();
๐Ÿ“Š

Quick Reference

Use this cheat sheet to remember key points about spy in Mockito:

ActionSyntaxNotes
Create spyMyClass spy = Mockito.spy(realObject);Wraps real object, calls real methods by default
Stub methodMockito.doReturn(value).when(spy).method();Avoids calling real method during stubbing
Verify callMockito.verify(spy).method();Checks if method was called on spy
AvoidMockito.when(spy.method()).thenReturn(value);May call real method, causing side effects
โœ…

Key Takeaways

Use Mockito.spy() to wrap real objects for partial mocking in JUnit tests.
Always stub spy methods with doReturn().when() to avoid calling real methods during stubbing.
Verify interactions on spy objects with Mockito.verify() as usual.
Be cautious of side effects since spies call real methods by default.
Mockito cannot spy on null or final objects without extra setup.