【问题标题】:How to test function returning Mono<Void> which has another Mono<T> within using Reactor's StepVerifier如何使用 Reactor 的 StepVerifier 测试返回具有另一个 Mono<T> 的 Mono<Void> 的函数
【发布时间】:2020-06-20 16:07:42
【问题描述】:

我有一个这样的 ServiceWebClientInterface.java

import reactor.core.publisher.Mono;

public interface ServiceWebClientInterface {

    Mono<String> apiCall();
}

MyClass.java

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;

public class MyClass extends AbstractGatewayFilterFactory<MyClass.Config> {

    private final ServiceWebClientInterface serviceWebClientInterface;

    MyClass(final ServiceWebClientInterface serviceWebClientInterface) {
        this.serviceWebClientInterface = serviceWebClientInterface;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            return serviceWebClientInterface.apiCall().flatMap(response -> {
                if (!"Valid".equals(response)) {
                    exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
                    return exchange.getResponse().setComplete();
                }
                return chain.filter(exchange);
            });

        };
    }

    public static class Config  {
        // Put the configuration properties
    }
}

我正在尝试使用 StepVerifier 对 myMethod 进行单元测试,但我无法在 myMethod 的内部 lambda 函数中执行语句。

MyClassTest.java

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
class MyClassTest {

    @Mock
    ServiceWebClientInterface mockServiceWebClientInterface;
    @Mock
    private ServerWebExchange mockServerWebExchange;
    @Mock
    private GatewayFilterChain mockGatewayFilterChain;
    @Mock
    private ServerHttpResponse mockServerHttpResponse;

    @BeforeEach
    void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void test_apply_forValid() {
        when(mockServiceWebClientInterface.apiCall()).thenReturn(Mono.just("Valid"));
        MyClass.Config config = new MyClass.Config();
        MyClass myClass = new MyClass(mockServiceWebClientInterface);

        GatewayFilter gatewayFilter = myClass.apply(config);

        Mono<Void> response = gatewayFilter.filter(mockServerWebExchange, mockGatewayFilterChain);

        StepVerifier.create(response).expectComplete();

        verify(mockServiceWebClientInterface).apiCall();
        verify(mockGatewayFilterChain).filter(mockServerWebExchange);

    }

    @Test
    void test_apply_forInValid() {
        when(mockServiceWebClientInterface.apiCall()).thenReturn(Mono.just("InValid"));
        when(mockServerWebExchange.getResponse()).thenReturn(mockServerHttpResponse);
        MyClass.Config config = new MyClass.Config();
        MyClass myClass = new MyClass(mockServiceWebClientInterface);

        GatewayFilter gatewayFilter = myClass.apply(config);

        Mono<Void> response = gatewayFilter.filter(mockServerWebExchange, mockGatewayFilterChain);

        StepVerifier.create(response).expectComplete();

        verify(mockServiceWebClientInterface).apiCall();
        verify(mockServerHttpResponse).setStatusCode(eq(HttpStatus.FORBIDDEN));
        verify(mockServerHttpResponse).setComplete();
        verify(mockGatewayFilterChain, never()).filter(mockServerWebExchange);

    }


}

请在上面找到完整的代码,当我运行测试时,我观察到内部 lambda 函数没有被使用步骤验证器调用。

【问题讨论】:

    标签: java reactive-programming spring-webflux project-reactor spring-reactor


    【解决方案1】:

    我猜你想测试实现MyLambda 接口的类。 正如代码 sn-p 中提到的那样,确保您在那里注入 serviceWebClientInterface

    要对该类进行单元测试,您应该模拟 serviceWebClientInterface.apiCall() 并验证它是否被调用。作为您实际代码 sn-p 的补充。

    您可以为此目的使用 Mockito 库。

    • 创建一个模拟:

    given(serviceWebClientInterface).willReturn(Mono.just("some text"));

    • 然后验证是否被调用:

    verify(serviceWebClientInterface).apiCall()

    【讨论】:

    • 是的,你是对的。正如您所提到的,我注入了 serviceWebClientInterface 和 Mock 。但是当我使用StepVerifier.create(resultMono).verifyComplete(); 并使用verify(serviceWebClientInterface).apiCall() 进行验证时,我发现它没有被调用。
    【解决方案2】:

    我能够通过使用
    解决这个问题 StepVerifier.create(response).verifyComplete();

    和模拟chain.filter(exchange);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-17
      • 2018-12-26
      • 2021-12-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 2019-01-02
      相关资源
      最近更新 更多