【问题标题】:TestNG + Mockito, how to test thrown exception and calls on mocksTestNG + Mockito,如何测试抛出的异常和调用模拟
【发布时间】:2016-05-18 09:12:08
【问题描述】:

在我的 TestNG 单元测试中,我有一个场景,我想测试抛出异常,但我也想测试在模拟子组件上没有调用某些方法。我想出了这个,但这很丑,很长而且可读性不好:

@Test
public void testExceptionAndNoInteractionWithMethod() throws Exception {

    when(subComponentMock.failingMethod()).thenThrow(RuntimeException.class);

    try {
        tested.someMethod(); //may call subComponentMock.methodThatShouldNotBeCalledWhenExceptionOccurs
    } catch (RuntimeException e) {
        verify(subComponentMock, never()).methodThatShouldNotBeCalledWhenExceptionOccurs(any());
        return;
    }

    fail("Expected exception was not thrown");
}

有没有更好的解决方案来测试 Exception 和 verify() 方法?

【问题讨论】:

  • 如果您使用 TestNG,那么对于预期的异常,您应该使用 @Test 注释的 expectedExceptions 属性而不是使用 try catch 块。
  • 但在那种情况下我无法使用 verify(),因为测试代码永远不会到达那里
  • @kordirko 感谢您的链接,但唯一可用的答案包含限制“仅支持高达 1.10.8 的 Mockito”。但是我会给它机会,即使我的 Mockito 版本是 1.10.19
  • @Michal 如果我是你,我会将这两个问题分开。首先,我将使用expectedExpections 属性检查是否引发了异常。然后是否从未调用过方法的第二个方面,我将使用@Test(dependsOnMethods = "testExceptionAndNoInteractionWithMethod") 对第一个定义的依赖项进行单独的测试(您可能希望将此依赖项方法重命名为testExpection 之类的名称)。我看到您将subComponentMock 存储为测试类属性,所以这对您来说根本不是问题。

标签: java unit-testing mockito testng


【解决方案1】:

我们决定使用断言框架。

when(subComponentMock.failingMethod()).thenThrow(RuntimeException.class);

Assertions.assertThatThrownBy(() -> tested.someMethod()).isOfAnyClassIn(RuntimeException.class);

verify(subComponentMock, never()).methodThatShouldNotBeCalledWhenExceptionOccurs(any());

【讨论】:

    【解决方案2】:

    我会通过创建两个测试并使用注释属性 expectedExceptionsdependsOnMethods 来区分这两个问题。

    @Test(expectedExceptions = { RuntimeExpcetion.class } )
    public void testException() {
        when(subComponentMock.failingMethod()).thenThrow(RuntimeException.class);
        tested.someMethod(); //may call subComponentMock.methodThatShouldNotBeCalledWhenExceptionOccurs
    }
    
    @Test(dependsOnMethods = { "testException" } )
    public void testNoInteractionWithMethod() {
        verify(subComponentMock, never()).methodThatShouldNotBeCalledWhenExceptionOccurs(any());
    }
    

    对我来说,它看起来更整洁。你摆脱了try catch 块和不必要的fail 方法调用。

    【讨论】:

    • 感谢您的回答。我们团队开始了激烈的讨论,我会在之后回复。
    • 所以,我们终于找到了我们正在寻找的东西。这个解决方案带来了我们不喜欢的一件事——测试之间的依赖关系。我们认为,测试应该是独立的。我们选择的解决方案在我的回答中。
    猜你喜欢
    • 2013-04-21
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2013-02-15
    相关资源
    最近更新 更多