Bird
Raised Fist0
JUnittesting~20 mins

Argument captors in JUnit - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Argument Captor Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this JUnit test using ArgumentCaptor?

Consider the following JUnit test snippet using Mockito's ArgumentCaptor. What will be the value of captor.getValue() after the test runs?

JUnit
import static org.mockito.Mockito.*;
import org.mockito.ArgumentCaptor;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

interface Service {
    void process(String input);
}

public class TestClass {
    @Test
    void testArgumentCaptor() {
        Service mockService = mock(Service.class);
        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

        mockService.process("hello");
        mockService.process("world");

        verify(mockService, times(2)).process(captor.capture());

        String captured = captor.getValue();
        assertEquals("world", captured);
    }
}
A"hello"
B"world"
Cnull
DThrows an exception
Attempts:
2 left
💡 Hint

Remember that getValue() returns the last captured argument.

❓ assertion
intermediate
2:00remaining
Which assertion correctly verifies all captured arguments?

You have captured multiple arguments with an ArgumentCaptor. Which assertion correctly checks that the captured arguments are exactly ["one", "two", "three"] in order?

JUnit
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// assume mock.method called 3 times with "one", "two", "three"
verify(mock, times(3)).method(captor.capture());
List<String> capturedArgs = captor.getAllValues();
AassertEquals("three", captor.getValue());
BassertTrue(capturedArgs.containsAll(List.of("one", "two", "three")));
CassertEquals(3, capturedArgs.size());
DassertEquals(List.of("one", "two", "three"), capturedArgs);
Attempts:
2 left
💡 Hint

Check both order and content of the list.

🔧 Debug
advanced
2:00remaining
Why does this ArgumentCaptor test fail with "Wanted but not invoked" error?

Examine the test code below. Why does the verify statement fail with a "Wanted but not invoked" error?

JUnit
import static org.mockito.Mockito.*;
import org.mockito.ArgumentCaptor;
import org.junit.jupiter.api.Test;

interface Service {
    void execute(int value);
}

public class TestClass {
    @Test
    void testCaptorFail() {
        Service mockService = mock(Service.class);
        ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);

        // No call to mockService.execute here

        verify(mockService).execute(captor.capture());
    }
}
ABecause verify requires times(0) when no calls are made.
BBecause ArgumentCaptor cannot capture primitive types like int.
CBecause the method execute was never called on the mock, so verify fails.
DBecause captor.capture() must be called before verify.
Attempts:
2 left
💡 Hint

Check if the mocked method was called before verification.

🧠 Conceptual
advanced
1:30remaining
What is the main advantage of using ArgumentCaptor in tests?

Why do testers use ArgumentCaptor in unit tests with mocks?

ATo capture and assert the arguments passed to mocked methods for detailed verification.
BTo replace the need for mocking dependencies entirely.
CTo automatically generate test data for parameterized tests.
DTo speed up test execution by caching method calls.
Attempts:
2 left
💡 Hint

Think about what information ArgumentCaptor provides beyond simple call verification.

❓ framework
expert
2:30remaining
Which Mockito code snippet correctly captures and asserts multiple arguments in order?

Given a mock List<String> and calls mockList.add("a"), mockList.add("b"), mockList.add("c"), which code snippet correctly captures all arguments and asserts their order?

JUnit
import static org.mockito.Mockito.*;
import org.mockito.ArgumentCaptor;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;

List<String> mockList = mock(List.class);

mockList.add("a");
mockList.add("b");
mockList.add("c");
A
ArgumentCaptor&lt;String&gt; captor = ArgumentCaptor.forClass(String.class);
verify(mockList, times(3)).add(captor.capture());
assertEquals(List.of("a", "b", "c"), captor.getAllValues());
B
ArgumentCaptor&lt;String&gt; captor = ArgumentCaptor.forClass(String.class);
verify(mockList).add(captor.capture());
assertEquals(List.of("a", "b", "c"), captor.getAllValues());
C
ArgumentCaptor&lt;String&gt; captor = ArgumentCaptor.forClass(String.class);
verify(mockList, times(3)).add(anyString());
assertEquals(List.of("a", "b", "c"), captor.getAllValues());
D
ArgumentCaptor&lt;String&gt; captor = ArgumentCaptor.forClass(String.class);
verify(mockList, times(3)).add(captor.capture());
assertEquals("c", captor.getValue());
Attempts:
2 left
💡 Hint

Check the verify call and how many times add() is expected to be called.

Practice

(1/5)
1. What is the main purpose of using an ArgumentCaptor in JUnit tests with Mockito?
easy
A. To capture and inspect the arguments passed to a mocked method
B. To create a mock object for testing
C. To verify the number of times a method was called
D. To stub the return value of a method

Solution

  1. Step 1: Understand ArgumentCaptor role

    An ArgumentCaptor is used to catch the actual arguments passed to a mock's method during test execution.
  2. Step 2: Differentiate from other Mockito features

    Unlike mocks or verify count, ArgumentCaptor focuses on capturing and inspecting method arguments.
  3. Final Answer:

    To capture and inspect the arguments passed to a mocked method -> Option A
  4. Quick Check:

    ArgumentCaptor captures arguments [OK]
Hint: ArgumentCaptor catches method inputs for checking [OK]
Common Mistakes:
  • Confusing ArgumentCaptor with mock creation
  • Thinking it counts method calls
  • Assuming it stubs return values
2. Which of the following is the correct way to declare an ArgumentCaptor for a String argument in JUnit with Mockito?
easy
A. ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
B. ArgumentCaptor captor = new ArgumentCaptor<String>();
C. ArgumentCaptor<String> captor = new ArgumentCaptor<>();
D. ArgumentCaptor<String> captor = ArgumentCaptor.capture(String.class);

Solution

  1. Step 1: Recall ArgumentCaptor creation syntax

    The correct way is to use the static method forClass() with the class type.
  2. Step 2: Check each option for syntax correctness

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); uses ArgumentCaptor.forClass(String.class), which is correct. Options B and C incorrectly use constructors, which are not public. ArgumentCaptor<String> captor = ArgumentCaptor.capture(String.class); uses a non-existent method capture() for creation.
  3. Final Answer:

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); -> Option A
  4. Quick Check:

    Use forClass() to create captor [OK]
Hint: Use ArgumentCaptor.forClass(Type.class) to declare captor [OK]
Common Mistakes:
  • Trying to instantiate ArgumentCaptor with new
  • Using non-existent capture() method
  • Omitting the class type in forClass()
3. Given the following code snippet, what will be the captured argument value?
List<String> list = mock(List.class);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
list.add("hello");
verify(list).add(captor.capture());
String captured = captor.getValue();
medium
A. null
B. "hello"
C. "captor"
D. Throws an exception

Solution

  1. Step 1: Understand the mock and method call

    The mock list has add("hello") called, so "hello" is passed as argument.
  2. Step 2: Verify and capture argument

    The verify(list).add(captor.capture()) captures the argument passed to add(), which is "hello".
  3. Final Answer:

    "hello" -> Option B
  4. Quick Check:

    Captured argument matches method call input [OK]
Hint: Captured value equals argument passed to mock method [OK]
Common Mistakes:
  • Assuming captor captures method name
  • Expecting null if not stubbed
  • Thinking it throws exception without stubbing
4. Identify the error in the following test code using ArgumentCaptor:
ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
verify(mockedList).add(captor.capture());
mockedList.add(5);
Integer value = captor.getValue();
medium
A. ArgumentCaptor should be declared after method call
B. No error, code is correct
C. Captor must be reset before use
D. The verify call is before the actual method call

Solution

  1. Step 1: Analyze order of method call and verify

    The verify() call must come after the actual method call to check interactions.
  2. Step 2: Identify the mistake

    Here, verify() is called before mockedList.add(5), so no interaction is recorded yet.
  3. Final Answer:

    The verify call is before the actual method call -> Option D
  4. Quick Check:

    Verify after method call [OK]
Hint: Always call verify() after the method under test [OK]
Common Mistakes:
  • Calling verify before method invocation
  • Assuming captor resets automatically
  • Declaring captor after verify
5. You want to verify that a mocked service method was called twice with different String arguments, and capture both arguments for assertions. Which approach correctly uses ArgumentCaptor to achieve this?
hard
A. Use ArgumentCaptor only once; it cannot capture multiple calls
B. Create two separate ArgumentCaptors and verify each call separately
C. Use a single ArgumentCaptor and call getAllValues() after verifying two calls
D. Capture arguments by stubbing the method instead of verify

Solution

  1. Step 1: Understand multiple call verification with ArgumentCaptor

    A single ArgumentCaptor can capture all arguments from multiple calls using getAllValues().
  2. Step 2: Evaluate options for capturing multiple arguments

    Use a single ArgumentCaptor and call getAllValues() after verifying two calls correctly uses one captor and retrieves all captured arguments. Create two separate ArgumentCaptors and verify each call separately is unnecessary and verbose. Use ArgumentCaptor only once; it cannot capture multiple calls is false; captor supports multiple captures. Capture arguments by stubbing the method instead of verify is incorrect because stubbing does not capture arguments.
  3. Final Answer:

    Use a single ArgumentCaptor and call getAllValues() after verifying two calls -> Option C
  4. Quick Check:

    Single captor + getAllValues() captures multiple calls [OK]
Hint: Use getAllValues() on one captor for multiple calls [OK]
Common Mistakes:
  • Creating multiple captors unnecessarily
  • Thinking captor captures only one call
  • Trying to capture arguments via stubbing
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