0
0
JUnittesting~5 mins

Why advanced mocking handles complex dependencies in JUnit

Choose your learning style9 modes available
Introduction

Advanced mocking helps test parts of a program that depend on many other parts. It makes testing easier by pretending those parts work in a simple way.

When a method calls other methods from different classes that are hard to set up.
When testing a class that depends on external services like databases or web APIs.
When you want to isolate the code under test from complex or slow dependencies.
When you need to simulate different responses from dependencies to test all cases.
When dependencies have side effects that you want to avoid during testing.
Syntax
JUnit
import static org.mockito.Mockito.*;

// Create a mock object
MyDependency mockDep = mock(MyDependency.class);

// Define behavior for mock
when(mockDep.someMethod()).thenReturn(someValue);

// Use mock in test
MyClass obj = new MyClass(mockDep);
obj.methodUnderTest();

// Verify interactions
verify(mockDep).someMethod();

Use mock() to create fake objects that replace real dependencies.

when(...).thenReturn(...) sets what the mock should do when called.

Examples
This creates a mock of MyService and makes getData() return "mocked data".
JUnit
MyService mockService = mock(MyService.class);
when(mockService.getData()).thenReturn("mocked data");
This checks that process() was called exactly twice on the mock.
JUnit
verify(mockService, times(2)).process();
This makes the mock throw an exception when failMethod() is called, to test error handling.
JUnit
doThrow(new RuntimeException()).when(mockService).failMethod();
Sample Program

This test uses advanced mocking to replace the PaymentGateway dependency. It tests that processPayment returns true when the mock gateway charges successfully, and returns false without calling the gateway when the amount is zero.

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

class PaymentProcessor {
    private PaymentGateway gateway;
    public PaymentProcessor(PaymentGateway gateway) {
        this.gateway = gateway;
    }
    public boolean processPayment(double amount) {
        if (amount <= 0) return false;
        return gateway.charge(amount);
    }
}

interface PaymentGateway {
    boolean charge(double amount);
}

public class PaymentProcessorTest {
    @Test
    void testProcessPaymentSuccess() {
        PaymentGateway mockGateway = mock(PaymentGateway.class);
        when(mockGateway.charge(100.0)).thenReturn(true);

        PaymentProcessor processor = new PaymentProcessor(mockGateway);
        boolean result = processor.processPayment(100.0);

        assertTrue(result);
        verify(mockGateway).charge(100.0);
    }

    @Test
    void testProcessPaymentFailForZeroAmount() {
        PaymentGateway mockGateway = mock(PaymentGateway.class);
        PaymentProcessor processor = new PaymentProcessor(mockGateway);

        boolean result = processor.processPayment(0);

        assertFalse(result);
        verify(mockGateway, never()).charge(anyDouble());
    }
}
OutputSuccess
Important Notes

Advanced mocking helps isolate the code you want to test from complex parts.

Always verify that mocks are called as expected to catch mistakes.

Use mocking to simulate errors and edge cases that are hard to reproduce.

Summary

Advanced mocking makes testing easier by faking complex dependencies.

It helps test code in isolation and control dependency behavior.

Mockito is a popular tool for advanced mocking in JUnit tests.