首页 > 解决方案 > Spock 测试中的 SpringBootTest RestController 结果为 404

问题描述

给定下面的控制器代码,当我启动 spring boot 应用程序时,我可以对资源 /foo/id/{id} 进行 http 调用以获取数据。

但是,来自集成测试的相同调用返回 404。调用未触发休息控制器方法。测试没有将 http 调用转发到 rest 控制器。我错过了什么?

@RestController
@RequestMapping(“/foo”)
class FooResource {
@RequestMapping(method = RequestMethod.GET, path = “/id/{id}”)
String getData(@PathVariable int id) {
    logger.error("===== FooResource.getData called with {}", id)
     // more code
}
//more code

//Spock test case
@ContextConfiguration
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT
)
@EnableWebMvc
@AutoConfigureWebClient
@TestPropertySource(locations = "classpath:application-test.properties")
class IntegrationTest extends Specification {

    @Autowired
    RestTemplate restTemplate 


   @Configuration
   @ImportResource(["classpath*:/test-properties.xml", "classpath*:/springintegration-config.xml"])
   static class Beans {
        @Bean
        MessagingTemplate messagingTemplate() { new MessagingTemplate() }

        @Bean
        ServletWebServerFactory servletWebServerFactory() {
            return new TomcatServletWebServerFactory(9010);
        }

        @Bean
        public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
            return restTemplateBuilder
              .setConnectTimeout(30 * 1000)
                .setReadTimeout(30 * 1000)
               .build();
        }
   }

   def ‘foo resource returns the expected data for Id'() {
    given:
    int id = new SecureRandom().nextInt()
    TestRestTemplate restTemplate = new TestRestTemplate();

    when:
    ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:9010/foo/id/1234", String.class)

    then:
    assert response.statusCode == HttpStatus.OK
}

测试用例运行日志包括以下已经可用的映射

swsmmaRequestMappingHandlerMapping :将“{[/foo/id/{Id}],methods=[GET]}”映射到公共 java.lang.String com.foo.bar.rest.FooResource.getData(int)
2018-06-15 13:54:38.680 调试 20710 --- [main] osbfsDefaultListableBeanFactory:完成创建 bean 'requestMappingHandlerMapping' 的实例
2018-06-15 13:54:38.680 调试 20710 --- [main] osbfsDefaultListableBeanFactory:创建单例 bean 'mvcPathMatcher' 的共享实例
2018-06-15 13:54:38.681 调试 20710 --- [main] osbfsDefaultListableBeanFactory:创建 bean 'mvcPathMatcher' 的实例

标签: spring-mvcspring-bootspring-restcontrollerspring-boot-test

解决方案


更改 IntegrationTest 类的注释解决了这个问题。

//Spock test case
@SpringBootTest(
        classes = TestConfig.class,
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT
)
@AutoConfigureWebClient
@TestPropertySource(locations = "classpath:application-test.properties")
class IntegrationTest extends Specification {

    @Autowired
    RestTemplate restTemplate 


   @Configuration
   @ImportResource(["classpath*:/test-properties.xml", "classpath*:/springintegration-config.xml"])
   static class Beans {
        @Bean
        MessagingTemplate messagingTemplate() { new MessagingTemplate() }

        @Bean
        ServletWebServerFactory servletWebServerFactory() {
            return new TomcatServletWebServerFactory(9010);
        }

        @Bean
        public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
            return restTemplateBuilder
              .setConnectTimeout(30 * 1000)
                .setReadTimeout(30 * 1000)
               .build();
        }
   }

   def ‘foo resource returns the expected data for Id'() {
    given:
    int id = new SecureRandom().nextInt()
    TestRestTemplate restTemplate = new TestRestTemplate();

    when:
    ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:9010/foo/id/1234", String.class)

    then:
    assert response.statusCode == HttpStatus.OK
}

推荐阅读