Issue
I have an application that is using Spring Boot (latest version) and creating a back-end that has RESTful api's. Traditionally, I have created controllers like:
@RestController
@RequestMapping("/contacts")
public class ContactController {
@Autowired
private ContactService service;
@RequestMapping(value = "/contactId/{contactId}",
method = RequestMethod.GET, headers = "Accept=application/json")
public @ResponseBody ContactEntity getContactById(@PathVariable("contactId") long contactId) {
ContactEntity contactEntity = service.getContactById(contactId);
return contactEntity;
}
And an integrated test has always been like:
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = ServiceContextConfiguration.class)
@ComponentScan("com.tomholmes.springboot.phonebook.server")
@Transactional
@WebAppConfiguration
public class ContactControllerTest {
@Test
public void testGetContactById() throws Exception {
MockHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders.get(BASE_URL + "/contactId/6");
this.mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk());
}
}
This has always worked normally for years as a 'code first' api. Now, I am dealing with a contract-first API using OpenAPI 3 and a YAML file. The API is generated in the same location as before, and I would expect the test to work as it did before, but it does not.
So one resource:
[https://www.hascode.com/2018/08/testing-openapi-swagger-schema-compliance-with-java-junit-and-assertj-swagger/#API_Test]
is suggesting I use the assertj-swagger for the OpenAPI / Swagger contract testing.
Is this the only way to go? Is there no way for me to use my old traditional testing which I find extremely useful as an integrated test.
There is a third method I am also looking into: [https://www.testcontainers.org/modules/mockserver/] Which I am going to try also, and I am sure it will work.
I'm also wondering if there is code out there to auto-generate the Test just like there is to generate the API endpoint and the model, it would make sense if the Open API 3 also had the ability to generate the test was well.
Ultimately, I'd like to use my old way of testing if I could, but if not, then I'll try the other ways.
Solution
We had the same issue after switching to open api contract first with auto-generated controllers/delegate interfaces. The fix was to import the delegate impl in addition to the controller itself. Example:
@WebMvcTest(FeatureController.class)
@Import(FeatureDelegateImpl.class)
public class FeatureContractTest {
@Autowired
private MockMvc mvc;
@MockBean
private BusinessService businessService;
...
FeatureController
is the controller generated by open-api, which typically will be in a generated-sources folder within target. FeatureDelegateImpl
is our own implementation of the delegate interface, which lives in the src/main folder.
Answered By - etech
Answer Checked By - Mary Flores (JavaFixing Volunteer)