spring - 在 TestRestTemplate 中启用 Cookie 和重定向

标签 spring spring-boot spring-test

如何将 TestRestTemplate.HttpClientOption.ENABLE_REDIRECTSTestRestTemplate.HttpClientOption.ENABLE_COOKIES 添加到 spring-boots TestRestTemplate?

我正在使用 spring-boot,因此会自动为我配置一个 TestRestTemplate。

我可以在创建之前使用 RestTemplateBuilder 自定义此 bean。问题是我看不到如何添加这些选项:

    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
        return new RestTemplateBuilder()
                .errorHandler(new ResponseErrorHandler() {
                    ...
                });
    } 

documentation有一些接受这些选项的构造函数,但问题是 bean 已经为我创建了。

最佳答案

您可以创建一个 TestRestTemplate 并使用 @Bean 注释将其呈现给 Spring。

例如:

@Bean
@Primary
public TestRestTemplate testRestTemplate() {
    RestTemplate restTemplate = new RestTemplateBuilder()
            .errorHandler(new ResponseErrorHandler() {
                @Override
                public boolean hasError(ClientHttpResponse response) throws IOException {
                    return false;
                }

                @Override
                public void handleError(ClientHttpResponse response) throws IOException {

                }
            }).build();

    return new TestRestTemplate(restTemplate, user, password, TestRestTemplate.HttpClientOption.ENABLE_REDIRECTS, TestRestTemplate.HttpClientOption.ENABLE_COOKIES);
}

或者,如果您不需要自定义 RestTemplate,则使用以下构造函数(它在内部为您实例化 RestTemplate):

@Bean
@Primary
public TestRestTemplate testRestTemplate() {
    return new TestRestTemplate(TestRestTemplate.HttpClientOption.ENABLE_REDIRECTS, TestRestTemplate.HttpClientOption.ENABLE_COOKIES);
}

更新 1 以解决此评论:

when I run my tests, I now get the following error org.apache.http.ProtocolException: Target host is not specified

Spring 提供的 TestRestTemplate 配置为解析相对于 http://localhost:${local.server.port} 的路径。因此,当您将 Spring 提供的实例替换为您自己的实例时,您要么必须提供完整的地址(包括主机和端口),要么使用 LocalHostUriTemplateHandler 配置您自己的 TestRestTemplate > (您可以在 org.springframework.boot.test.context.SpringBootTestContextCustomizer.TestRestTemplateFactory 中看到此代码)。下面是后一种方法的示例:

@Bean
@Primary
public TestRestTemplate testRestTemplate(ApplicationContext applicationContext) {
    RestTemplate restTemplate = new RestTemplateBuilder()
            .errorHandler(new ResponseErrorHandler() {
                @Override
                public boolean hasError(ClientHttpResponse response) throws IOException {
                    return false;
                }

                @Override
                public void handleError(ClientHttpResponse response) throws IOException {

                }
            }).build();

    TestRestTemplate testRestTemplate =
            new TestRestTemplate(restTemplate, user, password, TestRestTemplate.HttpClientOption
                    .ENABLE_REDIRECTS, TestRestTemplate.HttpClientOption.ENABLE_COOKIES);

    // let this testRestTemplate resolve paths relative to http://localhost:${local.server.port}
    LocalHostUriTemplateHandler handler =
            new LocalHostUriTemplateHandler(applicationContext.getEnvironment(), "http");
    testRestTemplate.setUriTemplateHandler(handler);

    return testRestTemplate;
}

通过此 bean 配置,以下测试用例使用自定义的 TestRestTemplate 并成功调用本地主机上的 Spring Boot 应用程序:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RestTemplateTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void test() {
        ResponseEntity<String> forEntity = this.restTemplate.getForEntity("/some/endpoint", String.class);
        System.out.println(forEntity.getBody());
    }
}

关于spring - 在 TestRestTemplate 中启用 Cookie 和重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46782809/

相关文章:

java - 如何使用 JPA @Query 注释定义自定义查询

java - Docker将db容器与spring boot链接起来并获取环境变量

java - Spring security - oauth2 资源服务器测试

java - Spring @ConfigurationProperties 绑定(bind)在测试中失败

java - UnsatisfiedDependencyException Spring MVC 项目上下文根问题

java - 无法使用 Hibernate 从数据库中获取所有数据

java - Junit CXF REST API 和回滚测试数据

spring - 在 Spring 中配置特定的内存数据库以用于测试目的

java - 如何排除对象属性

java - Spring 安全: How to Return 503 Service Unavailable?