【问题标题】:Micronaut: Exception Handler is not invoked while executing Mockito testsMicronaut:执行 Mockito 测试时未调用异常处理程序
【发布时间】:2020-07-03 15:01:42
【问题描述】:

当我创建一个通过调用 API 由代码引发异常的情况时,ExceptionHandler 按预期调用。但是当我尝试通过单元测试创​​建相同的案例时,ExceptionHandler 没有被调用。我的课程如下:

Controller.java

@Post("/XXX")
public ResponseEntity<List<CategoryTopicBean>> listCategoryTopics(@Body CategoryIdsRequestBean categoryIdsRequestBean) {
    if (categoryIdsRequestBean.getCategoryIds().size() > MAX_ALLOWED_CATEGORY_SELECTION) {
        throw new CustomException(SystemConstants.ResponseCode.ERROR, SystemConstants.ResponseMessage.OVERFLOW_MAX_CATEGORIES);
    }
    ...

CustomExceptionHandler.java:

@Produces
@Singleton
@Requires(classes = {CustomException.class, ExceptionHandler.class})
public class CustomExceptionHandler implements ExceptionHandler<CustomException, HttpResponse> {

    @Override
    public HttpResponse handle(HttpRequest request, CustomException exception) {
        return HttpResponse.ok(new ResponseEntity<>(exception.responseCode, exception.getMessage()));
    }
}

XXXShould.java

@Test
public void should_list_category_topics() {
    CategoryIdsRequestBean categoryIdsBean = new CategoryIdsRequestBean();
    IdBean idBean = new IdBean();
    idBean.setId(ID_1);
    categoryIdsBean.setCategoryIds(Arrays.asList(idBean));

    ResponseEntity<List<CategoryTopicBean>> responseEntity = topicController.listCategoryTopics(categoryIdsBean);
    assertThat(SystemConstants.ResponseCode.SUCCESS).isEqualTo(responseEntity.getResponseCode());
    assertThat(1).isEqualTo(responseEntity.getData().size());

    categoryIdsBean = new CategoryIdsRequestBean();
    categoryIdsBean.setCategoryIds(Arrays.asList(idBean, idBean, idBean, idBean, idBean, idBean));
    responseEntity = topicController.listCategoryTopics(categoryIdsBean);
}

任何人都可以看看这个,并帮助我吗?

【问题讨论】:

  • 你有没有办法在单元测试期间测试异常处理程序?
  • 拜托,你能在你的问题中包括你如何在你的测试中初始化你的主题控制器吗?
  • 我个人曾尝试使用@Inject 注入控制器,但如果我这样做,则不会调用异常处理程序。
  • 所以,如果我理解正确的话,你是在直接实例化它,不是吗?如果是这样,@GoviS 的答案将是正确的:如果您直接实例化控制器,它只是一个普通的 java 类,没有框架提供的任何附加功能。这正是我问你topicontroller是如何初始化的原因。

标签: java unit-testing exception mockito micronaut


【解决方案1】:

这里的问题是,你是通过直接调用控制器方法来测试控制器 topicController.listCategoryTopics(categoryIdsBean).

这不是测试控制器功能的好方法。你应该做的是使用MicronautTest。 MicronautTest 将启动一个嵌入式服务器。现在您可以使用 HTTP 客户端访问端点并检索结果。

您的代码需要更改为以下几行。

@MicronautTest
class HelloWorldTest {

    @Inject
    @Client("/")
    RxHttpClient client;

    @Test
    public void should_list_category_topics() {
        // Test Data
        CategoryIdsRequestBean categoryIdsBean = new CategoryIdsRequestBean();
        IdBean idBean = new IdBean();
        idBean.setId(ID_1);
        categoryIdsBean.setCategoryIds(Arrays.asList(idBean));

        HttpRequest<String> request = HttpRequest.POST("/XXX", categoryIdsBean);
        ResponseEntity<List<CategoryTopicBean>> retrieve = client.toBlocking().retrieve(request, ResponseEntity.class);

        categoryIdsBean = new CategoryIdsRequestBean();
        categoryIdsBean.setCategoryIds(Arrays.asList(idBean, idBean, idBean, idBean, idBean, idBean));
        responseEntity = topicController.listCategoryTopics(categoryIdsBean);
    }
}

对于exception 的情况,由于异常处理程序返回ResponseEntity&lt;String&gt;,因此您需要对上述代码进行细微更改。

ResponseEntity<String> retrieve = client.toBlocking()
                               .retrieve(request, ResponseEntity.class);

如果您的控制器调用任何其他服务,请不要忘记模拟该行为。

【讨论】:

  • 是的,你是对的。但是我展示的代码是控制器的单元测试,而不是集成测试或功能测试。所以我需要编写如图所示的代码。有没有更好的方法进行单元测试?
  • @KrutiParekh 在单元测试中,您应该将被测方法视为独立单元,即您不应该在单元测试中检查异常处理程序逻辑。在我看来,你可以测试listCategoryTopicssize() &gt; MAX_ALLOWED_CATEGORY_SELECTION时是否抛出异常。集成测试用例更适合您的案例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多