Bird
Raised Fist0
JUnittesting~20 mins

Spy objects in JUnit - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Spy Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
1:30remaining
Purpose of Spy Objects in Unit Testing
What is the primary purpose of using a spy object in unit testing with JUnit?
ATo verify interactions with real objects while allowing actual method calls
BTo simulate exceptions without calling any real methods
CTo replace the entire implementation of a class with dummy methods
DTo generate random test data automatically during tests
Attempts:
2 left
💡 Hint
Think about how spies differ from mocks in terms of method calls.
❓ Predict Output
intermediate
2:00remaining
Output of Spy Verification in JUnit
What will be the result of running this JUnit test using Mockito spy?
JUnit
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;

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

        spyList.add("one");
        spyList.add("two");

        verify(spyList).add("one");
        verify(spyList).add("two");

        assert(spyList.size() == 2);
    }
}
ATest throws NullPointerException during spy creation
BTest passes successfully with both verifications and assertion true
CTest fails due to assertion error on spyList size
DTest fails because verify does not work on spy objects
Attempts:
2 left
💡 Hint
Remember that spy calls real methods unless stubbed.
❓ assertion
advanced
1:30remaining
Correct Assertion for Spy Method Call Count
Which assertion correctly verifies that a spy object's method was called exactly three times?
JUnit
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class SpyCallCountTest {
    public static class Calculator {
        public int add(int a, int b) { return a + b; }
    }

    @Test
    public void testAddCallCount() {
        Calculator calc = spy(new Calculator());
        calc.add(1, 2);
        calc.add(3, 4);
        calc.add(5, 6);

        // Which verify statement is correct?
    }
}
Averify(calc, atLeast(4)).add(anyInt(), anyInt());
Bverify(calc, times(1)).add(anyInt(), anyInt());
Cverify(calc, never()).add(anyInt(), anyInt());
Dverify(calc, times(3)).add(anyInt(), anyInt());
Attempts:
2 left
💡 Hint
Count how many times add() is called in the test.
🔧 Debug
advanced
2:00remaining
Debugging Spy Stubbing Issue
Why does the following test fail with a NullPointerException when stubbing a spy method?
JUnit
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class SpyStubTest {
    public static class Service {
        public String getData() { return "real data"; }
    }

    @Test
    public void testStubSpy() {
        Service service = spy(new Service());
        when(service.getData()).thenReturn(null);

        String result = service.getData();
        assert(result == null);
    }
}
ANullPointerException occurs because getData() returns null by default
BSpy object cannot stub any methods, only mocks can
CUsing when() on spy calls real method causing NullPointerException; use doReturn() instead
DTest fails because spy was not initialized with MockitoAnnotations
Attempts:
2 left
💡 Hint
Consider how Mockito handles stubbing on spies differently than mocks.
❓ framework
expert
2:30remaining
Spy Object Behavior in Integration Testing
In a JUnit integration test using Mockito spies, which statement about spy objects is TRUE?
ASpies allow partial mocking, so real methods run unless stubbed, useful for verifying side effects in integration tests
BSpies completely replace the real object, so no real methods are executed during integration tests
CSpies automatically reset their state after each test without additional configuration
DSpies cannot be used in integration tests because they only work with unit tests
Attempts:
2 left
💡 Hint
Think about how spies differ from mocks and their use cases beyond unit tests.

Practice

(1/5)
1. What is the main purpose of using a spy object in JUnit testing?
easy
A. To generate random data for testing
B. To completely replace the real object with a fake one
C. To observe real object behavior and verify method calls
D. To speed up test execution by skipping method calls

Solution

  1. Step 1: Understand spy object behavior

    A spy wraps a real object, allowing it to behave normally while tracking interactions.
  2. Step 2: Identify spy's main use

    Spies let you verify if certain methods were called without changing the real behavior.
  3. Final Answer:

    To observe real object behavior and verify method calls -> Option C
  4. Quick Check:

    Spy = observe real + verify calls [OK]
Hint: Spy watches real object calls without changing behavior [OK]
Common Mistakes:
  • Confusing spy with mock that replaces behavior
  • Thinking spy speeds up tests by skipping calls
  • Believing spy generates test data
2. Which of the following is the correct way to create a spy object using Mockito in JUnit?
easy
A. MyClass spy = Mockito.spy(new MyClass());
B. MyClass spy = Mockito.mock(MyClass.class);
C. MyClass spy = new MyClass();
D. MyClass spy = Mockito.verify(new MyClass());

Solution

  1. Step 1: Recall Mockito spy syntax

    Mockito creates a spy by wrapping a real instance: Mockito.spy(realObject).
  2. Step 2: Match options to syntax

    MyClass spy = Mockito.spy(new MyClass()); correctly uses Mockito.spy(new MyClass()) to create a spy.
  3. Final Answer:

    MyClass spy = Mockito.spy(new MyClass()); -> Option A
  4. Quick Check:

    Spy creation = Mockito.spy(real instance) [OK]
Hint: Spy wraps real instance with Mockito.spy() [OK]
Common Mistakes:
  • Using Mockito.mock() instead of spy()
  • Trying to spy without a real instance
  • Confusing verify() with spy()
3. Given the code below, what will be the output of the test?
List<String> list = new ArrayList<>();
List<String> spyList = Mockito.spy(list);
spyList.add("apple");
spyList.add("banana");
Mockito.verify(spyList).add("apple");
System.out.println(spyList.size());
medium
A. 0
B. Throws an exception
C. 1
D. 2

Solution

  1. Step 1: Understand spy behavior on add()

    Spy calls real methods, so add("apple") and add("banana") add elements to the list.
  2. Step 2: Verify method call and size

    Verification confirms add("apple") was called. The list now contains two elements, so size() returns 2.
  3. Final Answer:

    2 -> Option D
  4. Quick Check:

    Spy calls real methods, size = 2 [OK]
Hint: Spy calls real methods; size reflects added elements [OK]
Common Mistakes:
  • Assuming spy does not call real methods
  • Expecting size to be 0 after add calls
  • Confusing verify with changing behavior
4. Identify the error in the following test code using a spy:
List<String> list = new ArrayList<>();
List<String> spyList = Mockito.spy(list);
Mockito.when(spyList.size()).thenReturn(5);
spyList.add("orange");
System.out.println(spyList.size());
medium
A. Spy must be created with Mockito.mock()
B. Cannot stub spy methods with Mockito.when() directly
C. List cannot be spied because it's an interface
D. No error; output will be 1

Solution

  1. Step 1: Recognize stubbing on spy

    Stubbing spy methods with Mockito.when() can cause real method calls and errors.
  2. Step 2: Correct stubbing approach

    Use doReturn(5).when(spyList).size() to stub spy methods safely.
  3. Final Answer:

    Cannot stub spy methods with Mockito.when() directly -> Option B
  4. Quick Check:

    Spy stubbing = use doReturn() not when() [OK]
Hint: Stub spy methods with doReturn(), not when() [OK]
Common Mistakes:
  • Using Mockito.when() on spy causing real calls
  • Confusing spy creation with mock creation
  • Thinking interfaces can't be spied
5. You want to test a service method that calls a repository's save() method. You want to keep the real repository behavior but verify save() was called exactly once. Which is the best approach using spy objects?
hard
A. Create a spy of the repository, call the service method, then verify save() was called once
B. Mock the repository and stub save() to do nothing, then verify call count
C. Use a real repository without spy or mock and check database manually
D. Create a mock repository and verify save() was never called

Solution

  1. Step 1: Understand spy use case

    Spy lets real methods run while tracking calls, perfect for verifying save() without changing behavior.
  2. Step 2: Apply spy to repository and verify

    Create spy of repository, call service method, then verify save() was called once.
  3. Final Answer:

    Create a spy of the repository, call the service method, then verify save() was called once -> Option A
  4. Quick Check:

    Spy = real behavior + verify calls [OK]
Hint: Spy real repo to verify calls without changing behavior [OK]
Common Mistakes:
  • Mocking instead of spying loses real behavior
  • Checking database manually is slow and unreliable
  • Verifying save was never called contradicts test goal
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