Q24 of 40 · REST Assured
How do you mock external APIs that your service calls during a REST Assured test?
REST AssuredMidrest-assuredwiremockmockingintegration-testingapi-testing
Short answer
Short answer: Start a WireMock (or MockServer) instance before the suite and configure the service under test to call the mock's URL instead of the real external API. REST Assured tests the real service; WireMock stubs the external dependency. This lets you test error paths the real service would never return on demand.
Detail
REST Assured tests the API endpoint of your service. If that service calls a third-party API (payment gateway, email service, geocoder), you need to control what that third-party returns for deterministic tests.
WireMock approach (most common):
- Start WireMock on a known port before the suite
- Override the external service URL in your app config to point to WireMock
- Define stubs — what WireMock returns for given requests
- REST Assured tests your service as normal; WireMock intercepts the outbound call
@BeforeAll
static void startMock() {
wireMockServer = new WireMockServer(options().port(9999));
wireMockServer.start();
stubFor(post(urlEqualTo("/payments"))
.willReturn(aResponse().withStatus(200)
.withBody("{\"status\":\"APPROVED\"}")));
}
Use cases enabled by mocking:
- Test your service's behaviour when the payment gateway returns 503
- Test timeout handling when the external call takes > 5 seconds
- Test your service's response when the external API returns unexpected data
- Verify your service sends the correct request to the external API (WireMock verify)
// EXAMPLE
PaymentIntegrationTest.java
@WireMockTest(httpPort = 9999)
class PaymentIntegrationTest extends BaseApiTest {
@Test
void checkout_whenPaymentApproved_returns200() {
stubFor(post(urlEqualTo("/payment-gateway/charge"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"transactionId\":\"txn-123\",\"status\":\"APPROVED\"}")));
given(reqSpec)
.body(Map.of("orderId", "ord-99", "amount", 49.99))
.when()
.post("/checkout")
.then()
.statusCode(200)
.body("transactionId", equalTo("txn-123"))
.body("status", equalTo("APPROVED"));
}
@Test
void checkout_whenPaymentDeclined_returns402() {
stubFor(post(urlEqualTo("/payment-gateway/charge"))
.willReturn(aResponse().withStatus(402)
.withBody("{\"status\":\"DECLINED\"}")));
given(reqSpec)
.body(Map.of("orderId", "ord-99", "amount", 49.99))
.when()
.post("/checkout")
.then()
.statusCode(402)
.body("status", equalTo("DECLINED"));
}
}// WHAT INTERVIEWERS LOOK FOR
Knowing WireMock's role (stub the external dependency, not the service under test), how to wire the test app to call the mock URL, and the key value: testing error paths that real services won't produce on demand.
// COMMON PITFALL
Mocking the service under test itself rather than its dependencies. REST Assured should call the real running service — only external dependencies get mocked.