【问题标题】:Catching Exception with JUnit使用 JUnit 捕获异常
【发布时间】:2016-02-03 22:10:17
【问题描述】:

我正在为一个方法编写 JUnit 测试用例并增强我的 Cobertura 分支覆盖率,我想捕获异常,但不确定为什么测试没有捕获异常。

待测方法:

 public void getCondition( Map<String, Message> messagesMap ) throws EISClientException
{
    Message message = containsAMessageCode(getMessageCodes(), messagesMap);
    if(message!=null)
    {
        throw new EISClientException("One of the specified message code matched returned errors." + 
                message.getMessageCode() + ": " + message.getMessageType() + ": " + message.getMessageText());

    }
}

JUnit 测试:

@Test
public void testgetCondition() throws Exception {
    boolean caughtException = false;
    try {
        clientResponse = mock(ClientResponse.class);
        RetrieveBillingServiceResponse response = new RetrieveBillingServiceResponse();

        MessageToExceptionPostProcessFilter postProcessFilter = new MessageToExceptionPostProcessFilter();
        postProcessFilter.setCondition(ConditionOperator.OR);

        Message message = new Message();
        message.setMessageCode("200");
        message.setMessageType(MessageTypeEnum.MESSAGE_TYPE_INFO);
        message.setMessageText("Service completed successfully");

        response.setMessages(Arrays.asList(message));

        Map<String, Message> map = new HashMap<String, Message>();
        map.put("test", message);

        RetrieveBillingServiceResponse serviceResponse = postProcessFilter.getCondition(map);

    } catch (EISClientException ex) {
        caughtException = true;
        assertEquals("One of the specified message code matched returned errors.", ex.getMessage());
    }
    assertTrue(caughtException);
}

如果消息不为空,它应该捕获异常,但事实并非如此。我做错什么了吗?

谢谢,

【问题讨论】:

  • 我在您的测试中没有看到任何对 getCondition() 的调用。
  • 我更正了我的代码。我得到了两种类似的方法,并发布了错误的方法。

标签: java junit


【解决方案1】:

另一种测试预期异常被抛出的方法是在导致异常的被测代码行之后有一个fail()。

如果抛出异常,则跳转到 catch 并且永远不会调用 fail(),如果没有抛出异常,则 fail() 会在应该抛出异常的行之后执行,并且测试失败。

另外,请查看您当前的 assertEquals() - 您正在比较的字符串与您在创建异常时构建的字符串不同。

【讨论】:

    【解决方案2】:
    1. @yole 是对的。你还没有调用被测方法。
    2. 实现相同目的的更好方法是使用@Test(expected = .class) 注释- 当然- 您将无法检查消息。但是在您的情况下,被测方法仅抛出一个异常-只要您正在测试它是否会抛出该异常-应该没问题。不用说 cobertura - 会很开心! 这是一个教程: http://www.mkyong.com/unittest/junit-4-tutorial-2-expected-exception-test/

    【讨论】:

    • 在我的专业意见中,您永远不应该使用@ExpectException,您应该捕获异常并检查原因和消息,或者按照您的预期。只是我的专业意见。 :)
    • @Gavin ExpectedException 有一个 expectMessage 函数。
    【解决方案3】:

    您确定您的测试在某处调用getCondition() 方法吗?我从你的代码中看不到它。但如果您确定调用了getCondition(),请尝试使用!message.isEmpty() 而不是message!=null

    【讨论】:

    • 我在 RetrieveBillingServiceResponse 中调用 serviceResponse = postProcessFilter.getCondition(map);
    • 哦,是的,我现在明白了。在getCondition() 方法中使用!message.isEmpty() 而不是message!=null 怎么样?没有帮助?或者你的 Message 对象没有这个方法(isEmpty)?如果有,我认为问题可能出在这里,因为检查null和检查空是不一样的。
    【解决方案4】:

    这里有几件事不好:

    1. 对这种测试使用正确的注释

      @Test(预期 = EISClientException.class)

    2. 在一个单元测试中使用多个断言是一种不好的做法。请参阅 1 - 这应该可以解决它。

    3. 那么 containsAMessageCode(getMessageCodes(), messagesMap); .你确定这不返回 null 吗?如果你真的想对 getCondition 方法进行单元测试,你应该短路那个调用。

    4. catch (EISClientException ex) { ... } 中的 assertEquals 似乎不正常。您正在抛出带有更复杂消息的异常,因为您的代码现在看起来不会是真的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 2013-03-24
      相关资源
      最近更新 更多