Bird
Raised Fist0
JUnittesting~5 mins

@Spy for partial mocking in JUnit - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What is the purpose of the @Spy annotation in JUnit testing?
The @Spy annotation is used to create a partial mock of an object. It allows you to call real methods unless they are stubbed, combining real behavior with mock control.
Click to reveal answer
beginner
How does @Spy differ from @Mock in JUnit?
@Mock creates a full mock where all methods are stubbed and do nothing unless specified. @Spy wraps a real object and calls real methods by default, allowing selective stubbing.
Click to reveal answer
intermediate
Show a simple example of using @Spy in a JUnit test.
@Spy List<String> spyList = new ArrayList<>(); @Test void testSpy() { spyList.add("one"); verify(spyList).add("one"); assertEquals(1, spyList.size()); } This test uses @Spy to partially mock an ArrayList, calling real methods but verifying interactions.
Click to reveal answer
intermediate
What happens if you stub a method on a @Spy object?
When you stub a method on a @Spy object, the stubbed method returns the specified value instead of calling the real method. Other methods still call real implementations.
Click to reveal answer
beginner
Why might you choose @Spy over @Mock in testing?
Use @Spy when you want to test real behavior but still control or verify some method calls. It helps when you want to partially mock complex objects without rewriting all behavior.
Click to reveal answer
What does the @Spy annotation do in JUnit?
ACreates a full mock where all methods do nothing by default
BCreates a partial mock that calls real methods unless stubbed
CCreates a new instance of the class without mocking
DAutomatically verifies all method calls
Which statement is true about @Spy and @Mock?
A@Spy calls real methods by default; @Mock does not
B@Mock calls real methods by default; @Spy does not
CBoth call real methods by default
DNeither can be used with JUnit
If you stub a method on a @Spy object, what happens when that method is called?
AThe stubbed value is returned instead of calling the real method
BThe real method is always called ignoring the stub
CAn exception is thrown
DThe method call is ignored
Which of these is a good use case for @Spy?
AWhen you want to disable all method calls
BWhen you want to mock an interface with no implementation
CWhen you want to create a new object without mocking
DWhen you want to test real behavior but control some methods
In the example: @Spy List<String> spyList = new ArrayList<>(); spyList.add("one"); What will spyList.size() return?
AThrows an exception
B0
C1
DDepends on stubbing
Explain how @Spy works for partial mocking in JUnit and when you would use it.
Think about mixing real method calls with mocked behavior.
You got /4 concepts.
    Describe the difference between @Spy and @Mock annotations in JUnit testing.
    Focus on default method call behavior.
    You got /4 concepts.

      Practice

      (1/5)
      1. What does the @Spy annotation do in JUnit testing?
      easy
      A. Automatically runs all test methods in a class.
      B. Creates a completely fake object with no real method calls.
      C. Creates a real object but allows overriding some methods for partial mocking.
      D. Mocks static methods of a class.

      Solution

      1. Step 1: Understand @Spy purpose

        @Spy creates a real instance of the class but allows selective method overriding.
      2. Step 2: Compare with other mocking types

        Unlike full mocks, spies call real methods unless stubbed.
      3. Final Answer:

        Creates a real object but allows overriding some methods for partial mocking. -> Option C
      4. Quick Check:

        @Spy = Partial real object with override [OK]
      Hint: Remember: @Spy means real object with some fake methods [OK]
      Common Mistakes:
      • Confusing @Spy with @Mock which creates full fake objects
      • Thinking @Spy mocks static methods
      • Assuming @Spy runs tests automatically
      2. Which of the following is the correct way to initialize a spy object in a JUnit 5 test class using Mockito?
      easy
      A. @Spy MyClass mySpy; MockitoAnnotations.openMocks(this);
      B. @Spy MyClass mySpy = new MyClass();
      C. @Spy MyClass mySpy = Mockito.mock(MyClass.class);
      D. @Spy MyClass mySpy = Mockito.spy(null);

      Solution

      1. Step 1: Recognize proper spy initialization

        Using @Spy requires calling MockitoAnnotations.openMocks(this) to initialize the spy fields.
      2. Step 2: Check other options

        @Spy MyClass mySpy = new MyClass(); misses initialization call; C uses mock instead of spy; D tries spying on null which is invalid.
      3. Final Answer:

        @Spy MyClass mySpy; MockitoAnnotations.openMocks(this); -> Option A
      4. Quick Check:

        Initialize spies with openMocks(this) [OK]
      Hint: Always call MockitoAnnotations.openMocks(this) to init @Spy [OK]
      Common Mistakes:
      • Not calling MockitoAnnotations.openMocks(this)
      • Confusing spy creation with mock creation
      • Trying to spy on null or uninitialized objects
      3. Given the following code snippet, what will be the output of the test?
      @Spy
      List<String> spyList = new ArrayList<>();
      
      @Test
      void testSpyList() {
          spyList.add("one");
          spyList.add("two");
          Mockito.doReturn(100).when(spyList).size();
          System.out.println(spyList.size());
      }
      medium
      A. 2
      B. 100
      C. 0
      D. Throws NullPointerException

      Solution

      1. Step 1: Understand spy behavior with doReturn

        The spy calls real methods unless stubbed. Here, size() is stubbed to return 100.
      2. Step 2: Analyze output of spyList.size()

        Despite adding two elements, size() returns 100 due to stubbing.
      3. Final Answer:

        100 -> Option B
      4. Quick Check:

        Stubbed spy method returns stub value [OK]
      Hint: Stub spy methods with doReturn to override real calls [OK]
      Common Mistakes:
      • Expecting real method size() to return actual list size
      • Using when(spyList.size()) instead of doReturn for spies
      • Forgetting spy initialization causing NullPointerException
      4. Identify the error in the following test code using @Spy:
      @Spy
      MyService service;
      
      @Test
      void testService() {
          service = new MyService();
          Mockito.doReturn("mocked").when(service).getData();
          assertEquals("mocked", service.getData());
      }
      medium
      A. The spy object is not initialized with MockitoAnnotations.openMocks(this).
      B. You cannot assign a new instance to a @Spy annotated field.
      C. doReturn cannot be used with spy objects.
      D. The assertEquals method is used incorrectly.

      Solution

      1. Step 1: Check spy initialization

        The @Spy field must be initialized by calling MockitoAnnotations.openMocks(this) before use.
      2. Step 2: Analyze assignment and usage

        Assigning new instance manually is allowed but without initialization, spy won't work properly.
      3. Final Answer:

        The spy object is not initialized with MockitoAnnotations.openMocks(this). -> Option A
      4. Quick Check:

        Always init @Spy with openMocks(this) [OK]
      Hint: Always initialize @Spy fields before test runs [OK]
      Common Mistakes:
      • Forgetting to call MockitoAnnotations.openMocks(this)
      • Thinking manual assignment replaces initialization
      • Believing doReturn can't be used with spies
      5. You want to partially mock a complex service class PaymentProcessor to test only the processPayment() method while keeping other methods real. Which approach using @Spy is best to achieve this?
      hard
      A. Create a new PaymentProcessor instance without @Spy and call processPayment() directly.
      B. Mock the entire PaymentProcessor class with @Mock and implement processPayment() manually.
      C. Use @Spy but override all methods except processPayment() to avoid side effects.
      D. Create a spy of PaymentProcessor and stub only processPayment() method with Mockito.doReturn().

      Solution

      1. Step 1: Understand partial mocking goal

        Partial mocking means real methods run except those stubbed.
      2. Step 2: Choose spy with selective stubbing

        Using @Spy and stubbing only processPayment() lets you test that method while others behave normally.
      3. Step 3: Evaluate other options

        Mocking entire class loses real behavior; overriding all except one is complex; no spy means no partial mocking.
      4. Final Answer:

        Create a spy of PaymentProcessor and stub only processPayment() method with Mockito.doReturn(). -> Option D
      5. Quick Check:

        @Spy + stub target method = partial mocking [OK]
      Hint: Spy real object, stub only target method for partial mocking [OK]
      Common Mistakes:
      • Mocking entire class losing real method calls
      • Overriding too many methods manually
      • Not using @Spy for partial mocking
      Recommended

      Ready to prove it?

      Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

      10 questions~5 mineasy hard