Spring ,webflux : The getRemoteAddress method of the ServerHttpRequest object returns null when request performed from WebTestClient

标签 spring spring-test spring-webflux

我有一个 Controller

@RestController
public class NameController {

    @Autowired
    private NameService nameService;

    @GetMapping("/name")
    public Mono<UploadParamsDto> getName(ServerHttpRequest request) {
            return nameService.getNameByHost(request.getRemoteAddress().getHostName());
    }
}

我有一个测试方法:
@ExtendWith(SpringExtension.class)
@WebFluxTest(NameControllerTest.class)
@ActiveProfiles("test")
class NameControllerTest {

    @Autowired
    private WebTestClient webClient;

    @Test
    void nameTest() {
        webClient.get().uri("/name")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                .expectStatus()
                .isOk();
    }
}

当我运行测试以检查我的 getName 方法时,我得到了 NPE,因为
request.getRemoteAddress() 返回 null,你能告诉我如何模拟 ServerHttpRequest 吗? (我知道有 MockServerHttpRequest,但我无法使用它)

我的目的是让 request.getRemoteAddress().getHostName() 返回模拟值。

最佳答案

谢谢大家。
以下一种方式工作:

@ExtendWith(SpringExtension.class)
@WebFluxTest(NameControllerTest.class)
@ActiveProfiles("test")
class NameControllerTest {

    @Autowired
    private ApplicationContext context;

    @Test
    void nameTest() {

        WebTestClient webClient = WebTestClient
                    .bindToApplicationContext(context)
                    .webFilter(new SetRemoteAddressWebFilter("127.0.0.1"))
                    .configureClient()
                    .build();

        webClient.get().uri("/name")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                .expectStatus()
                .isOk();
    }
}

其中 SetRemoteAddressWebFilter 是 WebFilter:
public class SetRemoteAddressWebFilter implements WebFilter {

    private String host;

    public SetRemoteAddressWebFilter(String host) {
        this.host = host;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(decorate(exchange));
    }

    private ServerWebExchange decorate(ServerWebExchange exchange) {
        final ServerHttpRequest decorated = new ServerHttpRequestDecorator(exchange.getRequest()) {
            @Override
            public InetSocketAddress getRemoteAddress() {
                return new InetSocketAddress(host, 80);
            }
        };

        return new ServerWebExchangeDecorator(exchange) {
            @Override
            public ServerHttpRequest getRequest() {
                return decorated;
            }
        };
    }
}

关于 Spring ,webflux : The getRemoteAddress method of the ServerHttpRequest object returns null when request performed from WebTestClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53761649/

相关文章:

java - org.springframework.beans.factory.UnsatisfiedDependencyException : Error creating bean with name 'documentationPluginsBootstrapper' defined

java - 如何模拟配置类进行测试

Java:从 Play Framework 应用程序使用 Spring WebFlux 应用程序

spring - 使用 JUnit 5 并行测试执行并仍然受益于 Spring 的上下文缓存?

java - 找不到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)

spring - 使用@WebFluxTest 测试 RouterFunction

spring-boot - WebClient 第一次请求缓慢的解决方法

java - 多核性能如何与 Scala 中的执行上下文和线程池相关

java - 使用 Spring 和 AspectJ 拦截私有(private)方法

java - Spring Boot 替代索引页