使用@RestClientTest

时间:2017-11-28 17:55:56

标签: java resttemplate spring-boot-test mockrestserviceserver

我正在使用spring boot 1.5.8并想测试我的客户端:

@Component
public class RestClientBean implements RestClient {
  private Map<String, RestTemplate> restTemplates = new HashMap<>();

  @Autowired
  public RestClientBean(RestTemplateBuilder builder, SomeConfig conf) {
    restTemplates.put("first", builder.rootUri("first").build();
    restTemplates.put("second", builder.rootUri("second").build();
  }
}

进行以下测试:

@RunWith(SpringRunner.class)
@RestClientTest(RestClient.class)
public class RestClientTest {
  @Autowired
  private RestClient client;

  @Autowired
  private MockRestServiceServer server;

  @TestConfiguration
  static class SomeConfigFooBarBuzz {
    @Bean
    public SomeConfig provideConfig() {
        return new SomeConfig(); // btw. not sure why this works, 
                                 // but this is the only way 
                                 // I got rid of the "unable to load 
                                 // SomeConfig auto-wire" or something like this :)
                                 // Anyway not my main issue
                                 // EDIT: just realized that the whole 
                                 // @TestConfiguration part can be avoided by
                                 // adding SomeConfig.class to the classes in the
                                 // @RestClientTest annotation
    }
  }

  @Before
  public void setUp() throws Exception {
    server.expect(requestTo("/somePath")) // here an exception is thrown
                                          // (main issue)
          .andRespond(withSuccess("<valid json>", MediaType.APPLICATION_JSON));
  }
}

例外很清楚:

java.lang.IllegalStateException: Unable to use auto-configured 
MockRestServiceServer since MockServerRestTemplateCustomizer has been bound to 
more than one RestTemplate

但它是否可能以某种方式进行测试或是否允许在一个客户端类中实例化两个不同的休息模板? 我只需要在某些情况下使用第一个休息模板,在其他情况下使用第二个模板。

1 个答案:

答案 0 :(得分:5)

经过几天的调查并通过GitHub与春天的人们沟通后,我找到了一个解决方案,但我没有收到答案,这意味着我的解决方案可能对某人有价值:

@RunWith(SpringRunner.class)
@RestClientTest(RestClient.class)
public class RestClientTest {
  @Autowired
  private RestClient client;

  private MockRestServiceServer firstServer;
  private MockRestServiceServer secondServer;
  private static MockServerRestTemplateCustomizer customizer; 

  @TestConfiguration
  static class RestTemplateBuilderProvider {
    @Bean
    public RestTemplateBuilder provideBuilder() {
      customizer = new MockServerRestTemplateCustomizer();
      return new RestTemplateBuilder(customizer);
    }
  }

  @Before
  public void setUp() {
    Map<RestTemplate, MockRestServiceServer> servers = customizer.getServers();
    // iterate and assign the mock servers according to your own strategy logic
  }

  @Test
  public void someTest() {
    firstServer.expect(requestTo("/somePath"))
               .andRespond(withSuccess("some json body"), 
                           MediaType.APPLICATION_JSON));

    // call client

    // verify response
  }

基本上指定一些模拟服务器与您在客户端代码中使用的其余模板的数量相同,然后指定一个测试配置,提供带有自定义程序的休息构建器,以便您的客户端代码的其余模板将是通过此定制构建器构建。然后使用自定义程序将模拟服务器绑定到创建的其余模板,并根据需要定义对它们的期望。