Suppose a live API returns fields that consumers can see but its published reference omits. A code-based schema test calls the API and asserts that the response conforms to its OpenAPI definition. It provides an additional check when the definition cannot be generated from the service, or when generated definitions miss behavior elsewhere in the request path. section 7.2 section 7.0
The test can assert individual rules, such as a property’s type and maximum length, or pass the OpenAPI definition to a validation library. Individual assertions must be updated when the schema changes. Definition-driven validation keeps those rules in the definition while the test supplies a request and checks the resulting response. Checks can include response structure, content type, and headers. section 7.2 section 7.1
Catch undocumented fields
A Product response schema permits only id and name by setting additionalProperties: false. If the live response also contains numberOfReviews and reviewRating, validation should fail: the response exposes fields absent from the published definition. A test can report the mismatch, but the team must decide whether the API or the definition needs changing. section 7.1 section 7.2
Choose the test boundary according to the behavior you need to verify:
- End to end: call the deployed API, including its gateway. This checks the response consumers receive across the stack, but runs more slowly and is harder to debug and maintain. section 7.2 section 7.6
- Controller level: send a request directly to the controller with dependencies mocked as needed. This gives fast feedback across success and error responses, but cannot catch gateway behavior such as an API-key authentication response. section 7.2.2
Listing 7.2 Product controller schema test
package com.acmepetsupplies.productcatalog;
import com.acmepetsupplies.productcatalog.controller.ProductsApiController;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import static com.atlassian.oai.validator.mockmvc
.OpenApiValidationMatchers.openApi;
import static io.restassured.module.mockmvc.RestAssuredMockMvc.given;
@SpringBootTest
public class ControllerSchemaTest {
@Test
public void testGetProductController() {
given()
.standaloneSetup(
new ProductsApiController()) #1
.when()
.get
("/v1/catalog/products/612b4280-b5c0-4ad5-bce7-ede7ab2b90fc")
.then()
.assertThat()
.expect(openApi()
.isValid("../product-catalog-v1-0.oas.yaml")) #2
.statusCode(200);
}
}
The Java controller test sends GET through Rest Assured MockMvc, validates the response against an OpenAPI YAML file with Atlassian’s matcher, and asserts status 200. Run this kind of test without starting the full application server. section 7.2.2
Add tests for each new endpoint and the happy- and sad-path responses you need to cover; that maintenance grows with the API. Hand-written tests are particularly useful when a scenario must sequence several API calls to produce a complex state. If broad endpoint coverage matters more than custom sequences, consider tests generated from the OpenAPI definition instead. section 7.3 section 7.4
