spring MockWebServer在WebFlux中不模拟WebClient

46qrfjad  于 2023-06-21  发布在  Spring
关注(0)|答案(1)|浏览(146)

下面是使用Spring Webflux的代码。我遵循了这个reference,但仍然没有发生模拟,并且返回了源代码webclient响应,有人能帮助理解为什么吗?
服务代码:

@Service
class A {

    WebClient webClient;
    // other fields

    pubic A(Webclient webclient,
            /* other fields */) {
        this. webclient = webclient;
        // other fields
    }

    public Mono<ClassA> functionA() {
        return webclient
            .post()
            .uri(getUrl())
            .contentType("APPLICATION_FORM_URLENCODED")
            .body(BodyInserters.fromFormData(getFormData()))
            .retrieve()
            .bodyToMono(ClassA.class);
    }
}

服务测试代码:

class ATest {
    
    MockWebServer mockWebServer;
    A a;

    @BeforeEach
    public void beforeEach() {
        mockWebServer = new MockWebServer();
        mockWebServer.start();
        WebClient webClient = WebClient.create(mockWebServer.url("/").toString());
        a = new A(webclient, /* other fields */)
    }

    @AfterEach
    void afterEach() {
        mockWebServer.shutdown();
    }

    @Test
    public void testMethod() {
        mockWebServer.enqueue(new MockResponse()
                .setStatus("HTTP/1.1 200"));
        
        Mono<ClassA> result = a.functionA();

        StepVerifier
                .create(result)
                .expectSubscription()
                .verifyComplete();
    }
}
fae0ux8s

fae0ux8s1#

您没有包含WebClient的源代码,但是WebClient.create(提示您正在创建WebClient的示例。如果您希望这是一个mock,那么您需要将其分配给Mockito.mock(WebClient.class)
比如这个

WebClient webClient = Mockito.mock(WebClient.class);

您还需要在mock上定义行为,否则当它到达.uri()方法调用时将抛出一个NPE,因为mock上没有定义返回值。因此,您必须配置您的mock,以便为所有这些链接的方法正确返回。如果这是SpringWebClient,我相信它们会返回一个Builder,所以您也需要一个模拟的Builder。
就我个人而言,我会重写该测试,使其看起来像这样

@ExtendWith(MockitoExtension.class)
public class ATest {

    @Mock
    private WebClient webClient;

    @Mock
    private WebClient.RequestBodyUriSpec requestBodyUriSpec;

    @Mock
    private WebClient.ResponseSpec responseSpec;

    @Mock
    private Mono<A> mono;

    @InjectMocks
    A a;

    @Test
    public void testMethod() {
        when(webClient.post()).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.uri("someURI")).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.contentType(MediaType.APPLICATION_FORM_URLENCODED)).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.body(any(BodyInserters.FormInserter.class))).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.retrieve()).thenReturn(responseSpec);
        when(responseSpec.bodyToMono(A.class)).thenReturn(mono);

        Mono<A> result = a.functionA();
        A a = result.block();
    }
}

您需要替换变量以匹配方法的输出,例如替换getUrl()getFormData()中的值

相关问题