I am testing a controller using the @WebMvcTest annotation and MockMvc, it is working fine:
@WebMvcTest(MyController.class)
class MyControllerSpec extends Specification {
@Autowired
MockMvc mockMvc;
def "test"() {
def mockRequest = "something"
when: "we make call"
def response = mockMvc.perform(post("/getuser")
.contentType(MediaType.APPLICATION_JSON)
.content(mockRequest))
.andReturn().response
then: "we get response"
response.status == OK.value()
}
}
I read some articles online that we can use TestRestTemplate for integration testing. My question is that if I use TestRestTemplate, do I have to use it with @SpringBootTest annotation for SpringBoot test? The reason I am asking this is that we have many controllers in our springBoot application, and also the service/dao layer code. It seems that I have to create a TestConfigure.class for all the beans (even the beans for other controllers that I am not testing) for testing purpose, otherwise, I will get error like:
Unable to start EmbeddedWebApplicationContext
due to missing EmbeddedServletContainerFactory bean
My test code using TestRestTemplate:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
classes = [TestConfigure.class])
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
class MyControllerSpec extends Specification {
@LocalServerPort
private int port;
@Autowired
TestRestTemplate restTemplate
private String createURLWithPort(String uri) {
return "http://localhost:" + port + uri;
}
def "Integration Success Senario"() {
given: ""
when: "we try to get a user using a rest call"
def request = new User(name, address)
String jsonResponse =
restTemplate.postForObject(createURLWithPort("/getuser"),
request, String.class)
.....
}
}
The error just tells you that your integration test is missing a servlet container to run your web service under test. You just have to configure this container somehow. You can do it manually or allow Spring to do it the same way as it does when you use @SpringBootApplication
or @EnableAutoConfiguration
. So just put @EnableAutoConfiguration
on your integration test class or create test configuration by declaring a static class inside the test and mark put the annotation on it. As suggested in the comment, the following assumption is wrong
It seems that I have to create a TestConfigure.class for all the beans...
Here is the working example without any user-defined beans and where Spring just returns 404 for non-existing method:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
class MyControllerSpec extends Specification {
@LocalServerPort
private int port
@Autowired
TestRestTemplate restTemplate
def "Integration Success Senario"() {
given: ""
def request = new User("name", "address")
when: "we try to get a user using a rest call"
def response = restTemplate.postForObject(createURLWithPort("/getuser"), request, Map.class)
then:
response.status == 404
}
private String createURLWithPort(String uri) {
return "http://localhost:" + port + uri
}
@EnableAutoConfiguration //it configures the servlet container
@Configuration
static class TestConfig {
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.