使用 vert.x rxjava2 和 Mockito 模拟 http 响应 [英] Mocking a http response using vert.x rxjava2 and Mockito

查看:69
本文介绍了使用 vert.x rxjava2 和 Mockito 模拟 http 响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 rxjava vert.x (ver. 3.8.4) WebClient.我的客户将调用一些服务,因此,通过 Mockito(3.2.4 版),我正在测试它应该如何处理错误.这是我模拟服务响应的方式:

<预><代码>...JsonObject jsonResponse = new JsonObject();HttpResponse<缓冲区>httpResponse = Mockito.mock(HttpResponse.class);Mockito.when(httpResponse.statusCode()).thenReturn(500);Mockito.when(httpResponse.bodyAsJsonObject()).thenReturn(jsonResponse);HttpRequest<缓冲区>httpRequest = Mockito.mock(HttpRequest.class);Mockito.when(httpRequest.rxSend()).thenReturn(Single.just(httpResponse));返回 httpRequest;...

作为 Mockito.when(httpResponse.statusCode()).thenReturn(500); 被执行我得到这个错误:

org.mockito.exceptions.misusing.UnfinishedStubbingException:此处检测到未完成的存根:->在 my.dummy.project.ServiceHandlerTest.serviceRepliesWithA500Response(ServiceHandlerTest.java:70)例如.thenReturn() 可能会丢失.正确存根的例子:当(mock.isOk()).thenReturn(true);when(mock.isOk()).thenThrow(exception);doThrow(exception).when(mock).someVoidMethod();提示:1. 缺少 thenReturn()2. 你试图存根一个不受支持的最终方法3.在thenReturn"指令完成之前,您正在阻止另一个模拟的行为...

我在这里遗漏了什么?

解决方案

我的建议是将 okhttp 的 MockWebServer 用于此类测试用例.

MockWebserver 可以为每个测试实例化,并允许您创建一个网络服务 url,您的被测实现可以使用该 url 向它发送一个真正的 http 请求.

在此之前,您可以定义一个模拟响应,该响应将由模拟网络服务器返回给您的实现.

我不知道你的测试用例,但是这个片段应该清楚 MockWebServer 是如何工作的.

更多示例和完整文档可以在 他们的 github 存储库.

正如你在下面看到的,你可以做出几个断言,例如.如果使用了正确的请求方法,有多少请求被触发,请求过程中是否使用了正确的请求参数和正文.

 @ExtendWith(VertxExtension.class)@Slf4j公共类 WebServiceTest {私有 WebServiceRequester sut;私有 MockWebServer mockWebServer;@BeforeEach公共无效设置(){sut = 新的 WebServiceRequester();mockWebServer = new MockWebServer();}@测试public void testCallService(final Vertx vertx, final VertxTestContext testContext) 抛出 InterruptedException {//给定final JsonObject requestPayload = new JsonObject().put("requestData", new JsonArray("[]"));final JsonObject serverResponsePayload = new JsonObject().put("responseData", new JsonArray("[]"));mockWebServer.enqueue(new MockResponse().setBody(serverResponsePayload.encode()).setResponseCode(200).setHeader("content-type", "application/json"));//什么时候final String webServiceUrl = mockWebServer.url("/").toString();最终承诺字符串承诺 =sut.callService(网络服务网址,请求有效载荷,顶点);//然后最终 RecordedRequest RecordedRequest = mockWebServer.takeRequest();assertEquals("POST",recordedRequest.getMethod());assertEquals("[text={\"request\":[]}]", recordsRequest.getBody().toString());assertEquals(1, mockWebServer.getRequestCount());testContext.assertComplete(stringPromise.future()).map(val -> {assertEquals("promise_completed", val);testContext.completeNow();返回值;}).onComplete(onComplete -> {assertTrue(onComplete.succeeded());日志信息(完成");}).onFailure(onError -> Assertions.fail());}}

I'm playing with the rxjava vert.x (ver. 3.8.4) WebClient. My client will call some services so, by Mockito (ver. 3.2.4) I'm testing how it should handle an error. Here is how I mock the service's response:

...
JsonObject jsonResponse = new JsonObject();
HttpResponse<Buffer> httpResponse = Mockito.mock(HttpResponse.class);
Mockito.when(httpResponse.statusCode()).thenReturn(500);
Mockito.when(httpResponse.bodyAsJsonObject()).thenReturn(jsonResponse);
HttpRequest<Buffer> httpRequest = Mockito.mock(HttpRequest.class);
Mockito.when(httpRequest.rxSend()).thenReturn(Single.just(httpResponse));
return httpRequest;
...

as the Mockito.when(httpResponse.statusCode()).thenReturn(500); is executed I get this error:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at my.dummy.project.ServiceHandlerTest.serviceRepliesWithA500Response(ServiceHandlerTest.java:70)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed
...

What am I missing here?

解决方案

My advice would be to use okhttp's MockWebServer for this kind of test case.

MockWebserver can be instantiated for each test and will allow you to create a webservice url that can be used by your implementation under test to send a real http request against it.

Before that you can define a mock response that will be returned by the mockwebserver to your implementation.

I don't know your test case, but this snippet should make clear how MockWebServer works.

More examples and the full docu can be found at their github repo.

As you can see below, you can make a couple of assertions, eg. if the correct request method has been used, how many requests were fired and if the correct request parameters and body were used during the request.

    @ExtendWith(VertxExtension.class)
    @Slf4j
    public class WebServiceTest {

        private WebServiceRequester sut;

        private MockWebServer mockWebServer;

        @BeforeEach
        public void setUp() {
            sut = new WebServiceRequester();
            mockWebServer = new MockWebServer();
        }

        @Test
        public void testCallService(final Vertx vertx, final VertxTestContext testContext) throws InterruptedException {
            // given
            final JsonObject requestPayload = new JsonObject().put("requestData", new JsonArray("[]"));
            final JsonObject serverResponsePayload = new JsonObject().put("responseData", new JsonArray("[]"));
            mockWebServer.enqueue(new MockResponse()
                                      .setBody(serverResponsePayload.encode())
                                      .setResponseCode(200)
                                      .setHeader("content-type", "application/json"));

            // when
            final String webServiceUrl = mockWebServer.url("/").toString();
            final Promise<String> stringPromise =
                sut.callService(
                    webServiceUrl,
                    requestPayload,
                    vertx);

            // then
            final RecordedRequest recordedRequest = mockWebServer.takeRequest();
            assertEquals("POST", recordedRequest.getMethod());
            assertEquals("[text={\"request\":[]}]", recordedRequest.getBody().toString());
            assertEquals(1, mockWebServer.getRequestCount());
            testContext.assertComplete(stringPromise.future())
                       .map(val -> {
                           assertEquals("promise_completed", val);
                           testContext.completeNow();
                           return val;
                       })
                       .onComplete(onComplete -> {
                           assertTrue(onComplete.succeeded());
                           log.info("done");
                       })
                       .onFailure(onError -> Assertions.fail());

        }
    }

这篇关于使用 vert.x rxjava2 和 Mockito 模拟 http 响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆