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.
Why advanced mocking handles complex dependencies in 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.
MyService and makes getData() return "mocked data".MyService mockService = mock(MyService.class); when(mockService.getData()).thenReturn("mocked data");
process() was called exactly twice on the mock.verify(mockService, times(2)).process();failMethod() is called, to test error handling.doThrow(new RuntimeException()).when(mockService).failMethod();
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.
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()); } }
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.
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.
Practice
Solution
Step 1: Understand the purpose of mocking
Mocking replaces real dependencies with fake ones to isolate the code being tested.Step 2: Recognize the benefit of advanced mocking
Advanced mocking allows control over complex dependencies, making tests reliable and focused.Final Answer:
To isolate the code under test and control the behavior of its dependencies -> Option BQuick Check:
Mocking isolates dependencies [OK]
- Thinking mocking speeds up production code
- Believing mocking removes the need for tests
- Confusing mocking with UI generation
Solution
Step 1: Recall Mockito mock creation syntax
Mockito uses the static method mock(Class) to create mock objects.Step 2: Verify the correct syntax
The correct syntax is: MyClass mock = Mockito.mock(MyClass.class);Final Answer:
MyClass mock = Mockito.mock(MyClass.class); -> Option AQuick Check:
Mockito.mock(Class) creates mocks [OK]
- Using new keyword instead of Mockito.mock
- Calling non-existent Mockito methods
- Incorrect class reference syntax
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@Mock
Repository repo;
@InjectMocks
Service service;
@Test
void testGetData() {
when(repo.fetch()).thenReturn("data");
String result = service.getData();
assertEquals("data", result);
}
}
What will be the test result if
repo.fetch() is called inside service.getData()?Solution
Step 1: Understand Mockito annotations usage
@Mock creates a mock for Repository, and @InjectMocks injects it into Service.Step 2: Analyze the when-thenReturn setup
Calling repo.fetch() returns "data" as stubbed, so service.getData() returns "data".Final Answer:
Test passes because repo.fetch() returns mocked "data" -> Option DQuick Check:
Mock returns stubbed value [OK]
- Assuming mocks return null by default
- Forgetting to initialize mocks with @ExtendWith or MockitoAnnotations
- Confusing mock injection with real object creation
@ExtendWith(MockitoExtension.class)
class TestClass {
@Mock
Database db;
@Test
void testQuery() {
when(db.query("SELECT * FROM users")).thenReturn(null);
String result = db.query("SELECT * FROM users");
assertNotNull(result);
}
}
What is the problem with this test?
Solution
Step 1: Analyze the stubbed return value
The mock is set to return null for the query method call.Step 2: Check the assertion logic
The test asserts that the result is not null, but the stub returns null, so assertion fails.Final Answer:
The assertion will fail because the mock returns null -> Option AQuick Check:
Assertion contradicts stubbed null [OK]
- Ignoring that stub returns null
- Assuming syntax error without checking code
- Believing test passes with failing assertions
Solution
Step 1: Identify the need to isolate service from external APIs
Testing should avoid calling real APIs to keep tests fast and reliable.Step 2: Choose advanced mocking to simulate API behavior
Mockito mocks for API clients allow controlling responses and injecting them into the service.Final Answer:
Use Mockito to create mocks for both API clients and inject them into the service -> Option CQuick Check:
Mock external APIs to isolate service [OK]
- Testing with real APIs causing slow or flaky tests
- Hardcoding fake responses inside service code
- Avoiding tests due to complexity
Ready to prove it?
Pass the test and this pattern moves unknown
