DEV Community

Jasper Aurelio Villas
Jasper Aurelio Villas

Posted on

This is called interaction testing

what is going on here?


@Test 
void verifyGatewayIsCalledExactlyOnceWithCorrectAmount() { 
 when(mockGateway.charge(123)).thenReturn(true); 
 service.charge(new Order(123)); 

 // confirm we called charge(123) exactly once, no more, no less
 verify(mockGateway, times(1)).charge(123); 
 verifyNoMoreInteractions(mockGateway); 
}

Enter fullscreen mode Exit fullscreen mode

This test is verifying not just the outcome of calling service.charge(...), but how the method interacts with its dependency (PaymentGateway). This is called interaction testing—you're checking that the correct method was called, with the correct data, exactly the right number of times.

Let’s walk through it line by line:


🔧 when(mockGateway.charge(123)).thenReturn(true);
You're stubbing the mock so that if charge(123) is called, it returns true. This ensures the service method doesn’t fail due to an unexpected mock return.


🚀 service.charge(new Order(123));
You're calling the actual method under test. This is where OrderService calls mockGateway.charge(...) internally with the order's amount.


✅ verify(mockGateway, times(1)).charge(123);
This line is the heart of the test: it verifies that the mock's charge(123) method was called exactly once. If it was never called, or called with a different amount, or called more than once—it’ll fail.


🛑 verifyNoMoreInteractions(mockGateway);
This adds an extra safety check: you assert that no other interactions with mockGateway happened besides the charge(123) call. It's like saying: “Only this, and nothing else.”


Why this test is useful
This is a great sanity test to ensure that:

  • Your OrderService is doing what it should (delegating to the gateway)

  • You’re using that dependency correctly

  • No extra or accidental gateway calls sneak in later

This kind of verification is especially important in systems where external calls (e.g. APIs, payments, emails) need to happen precisely once, and not more.

Want to enhance this by verifying inputs with argument matchers, or checking that no calls happen for invalid orders? I’d love to show you!

Top comments (0)