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
✗ Incorrect
The @Spy annotation creates a partial mock that calls real methods unless you stub them.
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
✗ Incorrect
@Spy calls real methods unless stubbed; @Mock creates a full mock with no real method calls.
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
✗ Incorrect
Stubbing a method on a @Spy causes that method to return the stubbed value instead of calling the real method.
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
✗ Incorrect
@Spy is useful when you want to test real behavior but selectively control or verify 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
✗ Incorrect
Since @Spy calls real methods by default, adding "one" increases the list size to 1.
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
Step 1: Understand @Spy purpose
@Spy creates a real instance of the class but allows selective method overriding.
Step 2: Compare with other mocking types
Unlike full mocks, spies call real methods unless stubbed.
Final Answer:
Creates a real object but allows overriding some methods for partial mocking. -> Option C
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
Step 1: Recognize proper spy initialization
Using @Spy requires calling MockitoAnnotations.openMocks(this) to initialize the spy fields.
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.
Final Answer:
@Spy MyClass mySpy; MockitoAnnotations.openMocks(this); -> Option A
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?
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
Step 1: Understand partial mocking goal
Partial mocking means real methods run except those stubbed.
Step 2: Choose spy with selective stubbing
Using @Spy and stubbing only processPayment() lets you test that method while others behave normally.
Step 3: Evaluate other options
Mocking entire class loses real behavior; overriding all except one is complex; no spy means no partial mocking.
Final Answer:
Create a spy of PaymentProcessor and stub only processPayment() method with Mockito.doReturn(). -> Option D
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 unknownstrongwhile earning +1 Grip toward your certificate.