Choosing the right test double in JUnit - Build an Automation Script
import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; interface PaymentService { boolean processPayment(double amount); } class OrderProcessor { private final PaymentService paymentService; public OrderProcessor(PaymentService paymentService) { this.paymentService = paymentService; } public boolean placeOrder(double amount) { return paymentService.processPayment(amount); } } public class OrderProcessorTest { private PaymentService paymentServiceMock; private OrderProcessor orderProcessor; @BeforeEach void setup() { paymentServiceMock = mock(PaymentService.class); orderProcessor = new OrderProcessor(paymentServiceMock); } @Test void testPlaceOrderCallsProcessPayment() { when(paymentServiceMock.processPayment(anyDouble())).thenReturn(true); boolean result = orderProcessor.placeOrder(100.0); assertTrue(result, "placeOrder should return true"); verify(paymentServiceMock, times(1)).processPayment(100.0); } }
This test uses Mockito to create a mock of the PaymentService interface. In the @BeforeEach method, the mock is created and injected into the OrderProcessor instance.
In the test method, we configure the mock to return true for any payment amount using when(...).thenReturn(true). Then we call placeOrder(100.0) and assert that it returns true.
Finally, we verify that the processPayment method was called exactly once with the argument 100.0. This confirms that OrderProcessor correctly delegates payment processing to the PaymentService.
This approach uses a mock test double to isolate OrderProcessor from the real PaymentService, allowing us to test behavior without side effects.
Now add data-driven testing with 3 different payment amounts: 50.0, 100.0, and 200.0