首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模拟org.springframework.web.reactive.function.client.WebClient.ResponseSpec#onStatus输入参数

模拟org.springframework.web.reactive.function.client.WebClient.ResponseSpec#onStatus输入参数
EN

Stack Overflow用户
提问于 2019-12-30 12:02:10
回答 2查看 3.7K关注 0票数 1

考虑到下列守则:

代码语言:javascript
运行
复制
    public Mono<Void> doStuff() {

        return this.requestStuff()
            .onStatus(HttpStatus::is5xxServerError,
                    clientResponse -> {
                    aMethodIWouldLikeToTest(clientResponse);
                    return Mono.error(new MyCustomException("First error I would like to test"));
                    })
            .onStatus(HttpStatus::is4xxClientError,
                    clientResponse -> {
                    aMethodIWouldLikeToTest(clientResponse);
                    return Mono.error(new MyCustomException("Second error I would like to test"));
                    })
            .bodyToMono(String.class)
            .flatMap(x -> anotherMethodIManagedToTest(x)))

    }

我的第一个目标是测试使用以下方法实现的anotherMethodIManagedToTest(x):

代码语言:javascript
运行
复制
    import org.springframework.web.reactive.function.client.WebClient;

    ...

    @Mock
    private WebClient.ResponseSpec responseSpec;

    private String desiredInputParam = "There is another black spot on the sun today!";

    ...

    @Test
    public void allGood_anotherMethodIManagedToTest_success {

        ...

        ClassUnderTest classUnderTest = new classUnderTest()
        ClassUnderTest classUnderTestSpy = spy(classUnderTestSpy);
        doReturn(responseSpec).when(classUnderTestSpy).requestStuff();

        when(responseSpec.onStatus(any(), any())).thenReturn(responseSpec);
        when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just(desiredInputParam));

        Mono<Void> result = classUnderTestSpy.doStuff();

        // Bunch of assertions for anotherMethodIManagedToTest(String desiredInputParam) performed with success ...

    }

现在,我想创建额外的测试来测试5xServerError事件和4xClientError事件,但是我很难理解如何:

HttpStatus::is5xxServerError

  • Mock的响应HttpStatus::is4xxServerError

  • Mock

  • clientResponse的响应以测试aMethodIWouldLikeToTest(org.springframework.web.reactive.function.client.ClientResponse clientResponse)

对如何执行这些行动有任何建议吗?

请注意,我不能真正使用任何PowerMock替代方案(如果这是实现我的目标的唯一方法),所有使用标准Mockito的答案都是首选的。

EN

回答 2

Stack Overflow用户

发布于 2022-02-21 02:49:35

我很抱歉我的反应太晚了。可以在测试用例中使用mockito:

您需要让WebClient.ResponseSpec

  • you在onStatus方法

  • 中检查它,以便首先创建一个抽象类(以避免实现所有方法),实现HttpStatus可以从该类创建一个模拟,而不是在这个类中添加了两个方法:

代码语言:javascript
运行
复制
abstract class CustomMinimalForTestResponseSpec implements WebClient.ResponseSpec {

        public abstract HttpStatus getStatus();

        public WebClient.ResponseSpec onStatus(Predicate<HttpStatus> statusPredicate, Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction) {
            if (statusPredicate.test(this.getStatus())) exceptionFunction.apply(ClientResponse.create(HttpStatus.OK).build()).block();
            return this;
        }
      }

  • getStatus将用于设置HttpStatus:

代码语言:javascript
运行
复制
when(responseSpecMock.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR);

  • ,对于onStatus,您可以调用真正的方法:

代码语言:javascript
运行
复制
when(responseSpecMock.onStatus(any(Predicate.class),any(Function.class)))
   .thenCallRealMethod();

  • 这是测试类:

代码语言:javascript
运行
复制
package com.example.test;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.function.Function;
import java.util.function.Predicate;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;


@ExtendWith(MockitoExtension.class)
public class ExperimentalWebClientTest {

    @Mock
    private WebClient webClientMock;

    @InjectMocks
    private ExperimentalWebClient experimentalWebClient;

    @Mock
    private WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock;

    @Mock
    private WebClient.RequestHeadersSpec requestHeadersSpecMock;

    @Mock
    private CustomMinimalForTestResponseSpec responseSpecMock;

    @Test
    void shouldFailsWhenHttpStatus5xx() {
        //given
        when(webClientMock.get()).thenReturn(requestHeadersUriSpecMock);
        when(requestHeadersUriSpecMock.uri(any(Function.class)))
            .thenReturn(requestHeadersSpecMock);
        when(requestHeadersSpecMock.retrieve()).thenReturn(responseSpecMock);

        when(responseSpecMock.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR);

        when(responseSpecMock.onStatus(any(Predicate.class), any(Function.class))).thenCallRealMethod();

        //when + Then
        assertThrows(MyCustomException.class,
            () -> experimentalWebClient.doStuff(),
            "call fails with Internal Server Error") ;
    }


    abstract class CustomMinimalForTestResponseSpec implements WebClient.ResponseSpec {

        public abstract HttpStatus getStatus();

        public WebClient.ResponseSpec onStatus(Predicate<HttpStatus> statusPredicate, Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction) {
            if (statusPredicate.test(this.getStatus())) exceptionFunction.apply(ClientResponse.create(HttpStatus.OK).build()).block();
            return this;
        }

    }
}
票数 3
EN

Stack Overflow用户

发布于 2019-12-31 12:32:41

我认为我的问题的答案是,Mockito不是测试这种东西的合适工具。使用wiremock似乎是一种方便的方法

当我主要使用以下库进行测试时:

进口com.github.tomakehurst.wiremock.client.WireMock;

  • import org.springframework.test.context.junit4.SpringRunner;

  • import org.springframework.boot.test.context.SpringBootTest;

  • import org.springframework.test.web.reactive.server.WebTestClient;

我设法完成了这项工作。

如果您面临类似的问题,我建议您查看一下https://www.sudoinit5.com/post/spring-boot-testing-consumer/,所提供的示例与我为完成测试所做的类似。

然而,我仍然感兴趣的是,如果有人知道如何完成这个问题与莫奇托。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59530512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档