使用TestRestTemplate的Spring Boot测试是否始终需要@SpringBootTest注释

问题描述 投票:0回答:1

我正在使用@WebMvcTest注释和MockMvc测试控制器,它工作正常:

@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()
   }
}

我在网上阅读了一些文章,我们可以使用TestRestTemplate进行集成测试。我的问题是,如果我使用TestRestTemplate,我是否必须将它与@SpringBootTest注释一起用于SpringBoot测试?我问这个的原因是我们的springBoot应用程序中有很多控制器,还有service / dao层代码。似乎我必须为所有bean(甚至是我没有测试的其他控制器的bean)创建一个TestConfigure.class用于测试目的,否则,我将得到如下错误:

Unable to start EmbeddedWebApplicationContext 
due to missing EmbeddedServletContainerFactory bean

我使用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)

    .....
   }
 }
spring-boot groovy spock spring-boot-test
1个回答
0
投票

该错误只是告诉您,您的集成测试缺少一个servlet容器来运行您正在测试的Web服务。你只需要以某种方式配置这个容器。您可以手动执行或允许Spring以与使用@SpringBootApplication@EnableAutoConfiguration时相同的方式执行此操作。因此,只需将@EnableAutoConfiguration放在集成测试类上,或者通过在测试中声明一个静态类来创建测试配置,并在其上标记注释。正如评论中所建议的那样,以下假设是错误的

似乎我必须为所有bean创建一个TestConfigure.class ...

下面是没有任何用户定义的bean的工作示例,其中Spring仅为非现有方法返回404:

@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 {

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.