【问题标题】:How to configure Spring TestRestTemplate如何配置 Spring TestRestTemplate
【发布时间】:2017-02-16 11:21:47
【问题描述】:

我有一个 REST (spring-hateoas) 服务器,我想通过 JUnit 测试对其进行测试。因此我使用的是自动注入的TestRestTemplate

但是我现在如何向这个预配置的 TestRestTemplate 添加更多配置?我需要配置 rootURI 并添加拦截器。

这是我的 JUnit 测试类:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)      

public class RestEndpointTests {
  private Logger log = LoggerFactory.getLogger(this.getClass());

  @LocalServerPort
  int localServerPort;

  @Value(value = "${spring.data.rest.base-path}")   // nice trick to get basePath from application.properties
  String basePath;

  @Autowired
  TestRestTemplate client;    //  how to configure client?

  [... here are my @Test methods that use client ...]
}

The documentation sais that a static @TestConfiguration class can be used. 但在那个静态类中我无法访问localServerPortbasePath

  @TestConfiguration
  static class Config {

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
      String rootUri = "http://localhost:"+localServerPort+basePath;    // <=== DOES NOT WORK
      log.trace("Creating and configuring RestTemplate for "+rootUri);
      return new RestTemplateBuilder()
        .basicAuthorization(TestFixtures.USER1_EMAIL, TestFixtures.USER1_PWD)
        .errorHandler(new LiquidoTestErrorHandler())
        .requestFactory(new HttpComponentsClientHttpRequestFactory())
        .additionalInterceptors(new LogRequestInterceptor())
        .rootUri(rootUri);
    }

  }

我最重要的问题:为什么TestRestTemplate 不首先考虑application.properties 中的spring.data.rest.base-path?蜜蜂的想法不是完全预配置的,这个包装类的整个用例吗?

文档说

如果你使用@SpringBootTest 注解,TestRestTemplate 是 自动可用并且可以@Autowired 进入你的测试。如果你 需要自定义(例如添加额外的消息 转换器)使用 RestTemplateBuilder @Bean。

在完整的 Java 代码示例中看起来如何?

【问题讨论】:

    标签: java spring rest spring-data-rest


    【解决方案1】:

    我知道这是一个老问题,您现在可能已经找到了另一个解决方案。但无论如何,我都会像我一样为其他绊倒它的人回答。我遇到了类似的问题,最终在我的测试类中使用@PostConstruct 来构造一个根据我的喜好配置的TestRestTemplate,而不是使用@TestConfiguration。

        @RunWith(SpringJUnit4ClassRunner.class)
        @EnableAutoConfiguration
        @SpringBootTest(classes = {BackendApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
        public class MyCookieClientTest {
            @LocalServerPort
            int localPort;
    
            @Autowired
            RestTemplateBuilder restTemplateBuilder;
    
            private TestRestTemplate template;
    
            @PostConstruct
            public void initialize() {
                RestTemplate customTemplate = restTemplateBuilder
                    .rootUri("http://localhost:"+localPort)
                    ....
                    .build();
                this.template = new TestRestTemplate(customTemplate,
                     null, null, //I don't use basic auth, if you do you can set user, pass here
                     HttpClientOption.ENABLE_COOKIES); // I needed cookie support in this particular test, you may not have this need
            }
        }
    

    【讨论】:

      【解决方案2】:

      为了配置你的TestRestTemplate,官方documentation建议你使用TestRestTemplate,如下例所示(例如,添加一个Basic Authentication):

      public class YourEndpointClassTest {
          private static final Logger logger = LoggerFactory.getLogger(YourEndpointClassTest.class);  
      
          private static final String BASE_URL = "/your/base/url";
      
          @TestConfiguration
          static class TestRestTemplateAuthenticationConfiguration {
      
              @Value("${spring.security.user.name}")
              private String userName;
      
              @Value("${spring.security.user.password}")
              private String password;
      
              @Bean
              public RestTemplateBuilder restTemplateBuilder() {
                  return new RestTemplateBuilder().basicAuthentication(userName, password);
              }
          }
      
      
          @Autowired
          private TestRestTemplate restTemplate;
      
      //here add your tests...
      

      【讨论】:

      • 您也可以使用@Test @WithMockUser(username = "admin", password = "password", roles = "USER") 进行基本身份验证
      【解决方案3】:

      当我需要使用TestRestTemplate 来访问我们测试环境中远程服务器上的 REST 端点时,我遇到了一种情况。所以测试没有启动 Spring Boot 应用程序,而不仅仅是连接到远程端点并从那里使用 REST 服务。测试的配置更简单,执行速度更快,因为它没有构建复杂的 Spring (Boot) 上下文。这是我的配置的摘录:

      @RunWith(SpringRunner.class)
      public class RemoteRestTestAbstract {
      
      protected TestRestTemplate restTemplate;
      private static RestTemplateBuilder restTemplateBuilder;
      
      
      @BeforeClass
      public static void setUpClass() {
          restTemplateBuilder = new RestTemplateBuilder()
              .rootUri("http://my-remote-test-server.my-domain.com:8080/");
      }
      
      @Before
      public void init() {
          restTemplate = new TestRestTemplate(restTemplateBuilder);
          login();
      }
      
      //...
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-16
        • 2017-11-15
        • 1970-01-01
        • 1970-01-01
        • 2017-05-24
        • 1970-01-01
        • 2018-04-15
        • 1970-01-01
        • 2020-06-22
        相关资源
        最近更新 更多