Test Overview
This test demonstrates how different test doubles (dummy, stub, mock, spy) serve different purposes in unit testing. It verifies that each double behaves as expected in a simple calculator service scenario.
This test demonstrates how different test doubles (dummy, stub, mock, spy) serve different purposes in unit testing. It verifies that each double behaves as expected in a simple calculator service scenario.
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.mockito.Mockito; interface CalculatorService { int add(int a, int b); int subtract(int a, int b); } class Calculator { private final CalculatorService service; public Calculator(CalculatorService service) { this.service = service; } public int performAddition(int a, int b) { return service.add(a, b); } public int performSubtraction(int a, int b) { return service.subtract(a, b); } } public class CalculatorTest { @Test void testWithDummy() { // Dummy: passed but not used CalculatorService dummyService = new CalculatorService() { public int add(int a, int b) { return 0; } public int subtract(int a, int b) { return 0; } }; Calculator calc = new Calculator(dummyService); int result = calc.performAddition(5, 3); assertEquals(0, result, "Dummy returns default 0"); } @Test void testWithStub() { // Stub: returns fixed value CalculatorService stubService = new CalculatorService() { public int add(int a, int b) { return 8; } public int subtract(int a, int b) { return 0; } }; Calculator calc = new Calculator(stubService); int result = calc.performAddition(5, 3); assertEquals(8, result, "Stub returns fixed sum"); } @Test void testWithMock() { // Mock: verifies interaction CalculatorService mockService = Mockito.mock(CalculatorService.class); Mockito.when(mockService.add(5, 3)).thenReturn(8); Calculator calc = new Calculator(mockService); int result = calc.performAddition(5, 3); assertEquals(8, result, "Mock returns stubbed sum"); Mockito.verify(mockService).add(5, 3); } @Test void testWithSpy() { // Spy: partial real behavior + verification CalculatorService realService = new CalculatorService() { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } }; CalculatorService spyService = Mockito.spy(realService); Calculator calc = new Calculator(spyService); int result = calc.performAddition(5, 3); assertEquals(8, result, "Spy calls real method"); Mockito.verify(spyService).add(5, 3); } }
| Step | Action | System State | Assertion | Result |
|---|---|---|---|---|
| 1 | Test starts with dummy double | Calculator created with dummy service that returns 0 | Assert result equals 0 | PASS |
| 2 | Test runs with stub double | Calculator created with stub service returning fixed 8 for add | Assert result equals 8 | PASS |
| 3 | Test runs with mock double | Calculator created with mock service; add(5,3) stubbed to 8 | Assert result equals 8 and verify add(5,3) called | PASS |
| 4 | Test runs with spy double | Calculator created with spy wrapping real service; add method real | Assert result equals 8 and verify add(5,3) called | PASS |