Test doubles help us test parts of a program by replacing real parts with simple stand-ins. This makes testing easier and faster.
Choosing the right test double in JUnit
public class TestClass { @Test public void testMethod() { Dependency dep = mock(Dependency.class); // create a test double when(dep.someMethod()).thenReturn(someValue); // define behavior // use dep in the class under test } }
Use mock() to create a test double that imitates a real object.
Use when(...).thenReturn(...) to set what the test double should do when called.
Dependency and makes getData() return "TestData".Dependency dep = mock(Dependency.class); when(dep.getData()).thenReturn("TestData");
Dependency object but overrides getData() to return "SpyData".Dependency dep = spy(new Dependency());
doReturn("SpyData").when(dep).getData();someMethod() was called on the mock during the test.Dependency dep = mock(Dependency.class);
verify(dep).someMethod();This test uses a mock as a test double for Dependency. It sets getData() to return "hello". The Service class uses this mock, and the test checks if the output is "HELLO" and if getData() was called.
import static org.mockito.Mockito.*; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class Service { private final Dependency dep; public Service(Dependency dep) { this.dep = dep; } public String process() { return dep.getData().toUpperCase(); } } interface Dependency { String getData(); } public class ServiceTest { @Test public void testProcess() { Dependency dep = mock(Dependency.class); when(dep.getData()).thenReturn("hello"); Service service = new Service(dep); String result = service.process(); assertEquals("HELLO", result); verify(dep).getData(); } }
Mocks are good when you want to check interactions and control behavior.
Spies wrap real objects but let you override some behavior.
Choose the test double type based on what you want to test: behavior, state, or interaction.
Test doubles replace real parts to make testing easier and safer.
Use mocks to fake behavior and verify calls.
Pick the right test double type to match your test goal.
Practice
Solution
Step 1: Understand the purpose of mocks
Mocks are used to fake behavior and verify interactions, such as method calls.Step 2: Compare with other test doubles
Stubs provide fixed responses, fakes have working implementations, spies record calls but mocks are designed for verification.Final Answer:
Mock -> Option AQuick Check:
Verify calls = Mock [OK]
- Confusing stubs with mocks
- Using fake when verification is needed
- Thinking spies are the same as mocks
Solution
Step 1: Identify stub creation syntax
Stubs return fixed data; in Mockito, use when(...).thenReturn(...) to stub a method.Step 2: Check other options
Verify checks calls, mock creates mocks, spy wraps real objects; only when().thenReturn() stubs.Final Answer:
when(service.getData()).thenReturn("data"); -> Option BQuick Check:
Stub method = when().thenReturn() [OK]
- Using verify() to stub methods
- Confusing mock() with stub setup
- Using spy() instead of stub
List<String> list = mock(List.class); when(list.size()).thenReturn(5); assertEquals(5, list.size());
Solution
Step 1: Analyze mock behavior
The list is mocked, and size() is stubbed to return 5.Step 2: Check assertion
assertEquals(5, list.size()) compares 5 with stubbed return 5, so it passes.Final Answer:
Test passes because size() returns 5 -> Option AQuick Check:
Stubbed method returns set value [OK]
- Assuming default mock returns 0
- Expecting real method call on mock
- Confusing mock with spy behavior
@Test
void testServiceCall() {
Service service = mock(Service.class);
service.process();
verify(service.process());
}Solution
Step 1: Check verify syntax
verify() expects the mock object, then method call separately: verify(service).process();Step 2: Identify error in code
Current code calls verify(service.process()), which is incorrect syntax and causes compile error.Final Answer:
Incorrect use of verify; should be verify(service).process(); -> Option DQuick Check:
verify syntax = verify(mock).method() [OK]
- Calling verify with method call inside
- Forgetting to mock the object
- Confusing stub and verify usage
Solution
Step 1: Understand test goal
We want to avoid real charges but verify the payment method was called.Step 2: Choose test double type
Mocks fake behavior and verify calls, perfect for checking method calls without real effects.Step 3: Compare other options
Stubs return fixed data but don't verify calls; fakes have real logic; spies call real methods, risking real charges.Final Answer:
Use a mock to verify the payment method call -> Option CQuick Check:
Verify calls without real effect = Mock [OK]
- Using spy risks real external calls
- Using stub misses call verification
- Choosing fake adds unnecessary complexity
Ready to prove it?
Pass the test and this pattern moves unknown
