使用@RestClientTest对rest客户端进行Spring启动测试

rad*_*dio 8 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

通过以下测试:

@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));
  }
}
Run Code Online (Sandbox Code Playgroud)

例外很清楚:

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

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

rad*_*dio 7

经过几天的调查,并通过GitHub与Spring员工进行了交流,我找到了一个解决方案,但在这里未收到答案,这意味着我的解决方案可能对某人有价值:

@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
  }
Run Code Online (Sandbox Code Playgroud)

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