由于未绑定的RestTemplate,Spring-Boot RestClientTest未正确自动配置MockRestServiceServer

Jos*_*h C 8 java rest spring spring-boot

编辑:这个问题特别与spring-boot 1.4.0中引入的@RestClientTest注释有关,该注释用于替换工厂方法.

问题:

根据文档,@ RestClientTest应该正确配置MockRestServiceServer以在测试REST客户端时使用.但是,在运行测试时,我收到IllegalStateException,表示MockServerRestTemplateCustomizer尚未绑定到RestTemplate.

值得注意的是,我使用Gson进行反序列化而不是Jackson,因此排除.

有谁知道如何正确使用这个新的注释?我还没有找到任何需要更多配置的示例.

组态:

@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class})
public class ClientConfiguration {

...

   @Bean
   public RestTemplateBuilder restTemplateBuilder() {
       return new RestTemplateBuilder()
            .rootUri(rootUri)
            .basicAuthorization(username, password);
   }
}
Run Code Online (Sandbox Code Playgroud)

客户:

@Service
public class ComponentsClientImpl implements ComponentsClient {

    private RestTemplate restTemplate;

    @Autowired
    public ComponentsClientImpl(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }

    public ResponseDTO getComponentDetails(RequestDTO requestDTO) {
        HttpEntity<RequestDTO> entity = new HttpEntity<>(requestDTO);
        ResponseEntity<ResponseDTO> response = 
              restTemplate.postForEntity("/api", entity, ResponseDTO.class);
        return response.getBody();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试

@RunWith(SpringRunner.class)
@RestClientTest(ComponentsClientImpl.class)
public class ComponentsClientTest {

    @Autowired
    private ComponentsClient client;

    @Autowired
    private MockRestServiceServer server;

    @Test
    public void getComponentDetailsWhenResultIsSuccessShouldReturnComponentDetails() throws Exception {
        server.expect(requestTo("/api"))
            .andRespond(withSuccess(getResponseJson(), APPLICATION_JSON));

        ResponseDTO response = client.getComponentDetails(requestDto);
        ResponseDTO expected = responseFromJson(getResponseJson());

        assertThat(response, is(expectedResponse));
    }
}
Run Code Online (Sandbox Code Playgroud)

和例外:

java.lang.IllegalStateException: Unable to use auto-configured MockRestServiceServer since MockServerRestTemplateCustomizer has not been bound to a RestTemplate
Run Code Online (Sandbox Code Playgroud)

回答:

根据下面的答案,不需要将RestTemplateBuilder bean声明为上下文,因为它已由spring-boot自动配置提供.

如果项目是一个spring-boot应用程序(它有@SpringBootApplication注释),这将按预期工作.然而,在上述情况下,该项目是一个客户端库,因此没有主要应用程序.

为了确保RestTemplateBuilder在主应用程序上下文中正确注入(已删除的bean),组件扫描需要一个CUSTOM过滤器(@SpringBootApplication使用的过滤器)

@ComponentScan(excludeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)
})
Run Code Online (Sandbox Code Playgroud)

Der*_*ude 7

MockRestServiceServer实例应该从静态工厂构造,使用RestTemplate. 请参见文章对测试过程的详细描述。

在您的示例中,您可以执行以下操作:

@RunWith(SpringRunner.class)
@RestClientTest(ComponentsClientImpl.class)
public class ComponentsClientTest {

    @Autowired
    private ComponentsClient client;

    @Autowired
    private RestTemplate template;

    private MockRestServiceServer server;

    @Before
    public void setUp() {
        server= MockRestServiceServer.createServer(restTemplate);
    }

    /*Do your test*/
}
Run Code Online (Sandbox Code Playgroud)

  • 这种实例化方法在 spring-boot 1.4.0 中引入的测试增强之前使用。引入 @RestClientTest 是为了取消那个特定的工厂方法。http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-client (4认同)

aba*_*hel 5

您在两个地方都有RestTemplateBuilder。在ClientConfiguration类和ComponentsClientImpl类中。Spring Boot 1.4.0自动配置一个RestTemplateBuilder,可在需要时用于创建RestTemplate实例。从ClientConfiguration类中删除以下代码,然后运行测试。

 @Bean
 public RestTemplateBuilder restTemplateBuilder() {
   return new RestTemplateBuilder()
        .rootUri(rootUri)
        .basicAuthorization(username, password);
  }
Run Code Online (Sandbox Code Playgroud)