【问题标题】:unit testing @Suspended AsyncResponse controller单元测试@Suspended AsyncResponse 控制器
【发布时间】:2017-11-22 01:49:07
【问题描述】:

我正在升级为完全异步,并且我有一个现有测试,该测试使用模拟依赖项对控制器进行单元测试并测试各种路径。我不知道如何转换这个单元测试。我正在使用 dropwizard/jersey,我想测试的方法现在看起来像这样

 @POST
public void getPostExample(final Map body, @Suspended final AsyncResponse
 asyncResponse){}

旧测试使用 mockito/junit 并使用 @InjectMocks 作为控制器,然后调用 getPostExample 上的方法并断言响应中的一些信息。它调用的服务是模拟的,但是当我搜索如何手动获取它以返回数据时,我找不到太多。我可以访问 AsyncResponse 但在调用带有结果的简历的真实代码中。我应该在测试中调用简历吗?

【问题讨论】:

  • 我发现很多东西都是创建一个客户端来执行请求,但我真的不想启动所有内容并测试实际的 HTTP 调用,除非我必须并且也许可以将其更改为集成测试。

标签: java unit-testing junit jersey dropwizard


【解决方案1】:

“我应该在我的测试中调用 resume”。不,你应该做的是测试 resume 方法是否使用预期的参数调用。这就是您测试方法的行为的方式。

您可以做的是使用 Mockito 的 ArgumentCaptor 来捕获传递给 resume 方法的 Response,然后对该 Response 进行断言。您需要模拟 AsyncResponse 才能使其正常工作。下面是一个例子

@RunWith(MockitoJUnitRunner.class)
public class AsyncMockTest {

    @Mock
    private AsyncResponse response;

    @Captor
    private ArgumentCaptor<Response> captor;

    @Test
    public void testAsyncResponse() {
        final TestResource resource = new TestResource();
        resource.get(this.response);

        Mockito.verify(this.response).resume(this.captor.capture());
        final Response res = this.captor.getValue();

        assertThat(res.getEntity()).isEqualTo("Testing");
        assertThat(res.getStatus()).isEqualTo(200);
    }

    @Path("test")
    public static class TestResource {
        @GET
        @ManagedAsync
        public void get(@Suspended AsyncResponse response) {
            response.resume(Response.ok("Testing").build());
        }
    }
}

【讨论】:

  • 在进行断言之前,您可能需要等待所需的超时时间,否则断言语句将失败
  • @webjockey 这是一个带有模拟 AsyncResponse 的 单元测试(不是集成测试)。无需等待。
  • @peeskillet 我似乎得到“与此模拟的交互为零”错误。任何建议
  • 如果您在新线程上返回响应,那将会发生。如果您想忘记管理自己的线程,只需使用 @MangagedAsync 注释该方法,Jersey 将在内部为您管理线程。如果你这样做,那么你的代码看起来就像我上面的一样,那么测试就可以工作了。如果您正在管理自己的线程,那么您需要考虑交互不同步的事实并相应地修复测试。也许有一些倒计时闩锁。没有看到一些代码就无法判断。
  • @peeskillet 好的,我仍然看不到响应是如何返回的。我目前正在我的测试中应用 Thread.sleep 以获得响应。我正在使用 ManagedAsync 顺便说一句。
【解决方案2】:

添加mockitoafter()方法调用等待其他线程完成;这应该可以解决异常问题,例如: Mockito.verify(response, after(10000)).resume(this.captor.capture());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-12
    • 2017-06-26
    • 2011-12-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    相关资源
    最近更新 更多