0
0
JUnittesting~15 mins

Why mocking isolates units under test in JUnit - Automation Benefits in Action

Choose your learning style9 modes available
Verify that mocking dependencies isolates the unit under test
Preconditions (2)
Step 1: Create a mock of the Service class
Step 2: Inject the mock Service into the Calculator instance
Step 3: Call the Calculator's method that uses the Service
Step 4: Verify that the Calculator method returns the expected result based on the mock behavior
Step 5: Verify that the Service mock was called as expected
✅ Expected Result: The Calculator method returns the expected result without calling the real Service implementation, proving the unit is isolated
Automation Requirements - JUnit 5 with Mockito
Assertions Needed:
Assert that the Calculator method returns the expected value
Verify that the mock Service method was called exactly once
Best Practices:
Use @Mock and @InjectMocks annotations for cleaner setup
Use Mockito's when-thenReturn to define mock behavior
Use verify to check interactions with mocks
Keep tests focused on one unit only
Automated Solution
JUnit
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

// External service interface
interface Service {
    int getValue();
}

// Class under test
class Calculator {
    private final Service service;

    public Calculator(Service service) {
        this.service = service;
    }

    public int calculate() {
        // Uses service to get a value and adds 10
        return service.getValue() + 10;
    }
}

@ExtendWith(MockitoExtension.class)
public class CalculatorTest {

    @Mock
    Service serviceMock;

    @InjectMocks
    Calculator calculator;

    @Test
    void testCalculateWithMockedService() {
        // Arrange: define mock behavior
        when(serviceMock.getValue()).thenReturn(5);

        // Act: call method under test
        int result = calculator.calculate();

        // Assert: verify result is as expected
        assertEquals(15, result, "Calculator should add 10 to mocked service value");

        // Verify: service method was called once
        verify(serviceMock, times(1)).getValue();
    }
}

This test uses Mockito to create a mock of the Service interface. The Calculator depends on this service.

By mocking Service, we control its behavior to return 5 when getValue() is called.

This isolates the Calculator from the real Service implementation, so the test only verifies Calculator's logic.

The @Mock annotation creates the mock, and @InjectMocks injects it into the Calculator instance.

The test asserts that the result is 15 (5 from mock + 10), and verifies the mock method was called exactly once.

This shows how mocking isolates the unit under test by replacing dependencies with controlled mocks.

Common Mistakes - 4 Pitfalls
Not using @ExtendWith(MockitoExtension.class) causing mocks not to initialize
{'mistake': 'Calling real methods on dependencies instead of mocking', 'why_bad': 'Test depends on external code, breaking isolation and making tests flaky or slow', 'correct_approach': "Use Mockito's when-thenReturn to define mock behavior and avoid calling real implementations"}
Not verifying interactions with mocks
Mixing multiple units in one test
Bonus Challenge

Now add data-driven testing with 3 different mock return values and expected results

Show Hint