【问题标题】:Spring boot testing of a rest client using @RestClientTest使用 @RestClientTest 对 Rest 客户端进行 Spring Boot 测试
【发布时间】:2018-05-12 06:58:55
【问题描述】:

我正在使用 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

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

【问题讨论】:

    标签: java resttemplate spring-boot-test mockrestserviceserver


    【解决方案1】:

    经过几天的调查和通过 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
      }
    

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

    【讨论】:

    • 感谢您发帖,因为我遇到了同样的问题。我想看看我怎样才能发现地图中的 RestTemplate 是我在我的 RestClient 中使用的。我在我的配置类中定义了 2 个带有限定符的 Rest 模板,我分别在我的 RestClient1 和 RestClient2 中自动装配。我不在同一个 RestClient 中使用两个 RestTemplates。
    • 忽略我的问题,因为我能够从 Appconfig 中提取特定的 restTemplate 并比较以获得正确的 MockRestServiceServer 实例 - ' RestTemplate rt=BeanFactoryAnnotationUtils.qualifiedBeanOfType(ctx.getBeanFactory(), RestTemplate.class, "OneRestTemplate ");'
    • 我觉得这个功能实现起来很奇怪,大多数情况下在resttemplate bean上就足够了,测试不需要做这个巫术
    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2021-02-02
    • 1970-01-01
    • 2020-04-27
    • 2018-11-09
    • 2019-03-07
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多