测试异常时的单元测试最佳实践
Unit test Best Practices when testing Exceptions
所以我一直在对 android 应用程序进行单元测试,虽然有些情况下我测试了失败场景,但我并没有完全按照这个答案所建议的方式测试它们().
我按照下面代码中显示的方式对其进行了测试。答案是建议您在测试方法签名上使用 "throws Exception",因为如果它实际上引发了您不期望的异常,它将无法通过测试。但是,无论有没有那段代码,我都尝试过,但都以同样的方式失败了。
上面提供的答案也通过使用 "rule" 来进行这种测试,我没有使用过,因为我需要的一切都在我的 try catch 块中,并且实例化是在 @Before 中完成的方法。
@Test
public void testMethod() {
try{
//code that will throw exception
fail("Exception was not thrown");
} catch (/* types of exceptions */) {
//my asserts
}
}
我所追求的是哪种方法被认为是 "best practice" 及其背后的原因。
@Test
注释的 expected
属性用于定义检查是否引发特定异常的测试用例。或者,还有用于更具体控制的 @Rules
注释和有点过时的 "try-catch" 习语。有关示例,请参阅 this and the junit wiki。
@Test(expected = IllegalArgumentException.class)
我个人使用 assertThrows 并将结果分配给 Throwable,这样我就可以检查消息。
这样做的原因是,例如,当我需要检查 return IllegalArgument 的验证时,我可以检查消息是否是该字段的预期消息。
@Test
public void testSomething_shouldThrowException() {
String expectedMessage = "Exception running the method";
Throwable exception = Assertions.assertThrows(YourException.class, ()
-> {
bean.doSomething(dummyRequest);
});
Assert.assertEquals(expectedMessage, exception.getMessage());
}
因为这是用 JUnit4 标记的,所以我更喜欢使用 @Test 注释的预期属性
@Test(expected = NullPointerException.class)
但是,如果您需要检查抛出的异常的更多属性,您可以使用 ExpectedException,它非常强大:
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void whenExceptionThrown_thenRuleIsApplied() {
exceptionRule.expect(NumberFormatException.class);
exceptionRule.expectMessage("For input string");
Integer.parseInt("1a");
}
不过,我建议使用 JUnit 5,您可以在其中使用 Java 8 构造,例如传递 Lambda 进行检查,这使您的代码非常明确和简洁。
JUnit 4 和 JUnit 5 的好文章:https://www.baeldung.com/junit-assert-exception
所以我一直在对 android 应用程序进行单元测试,虽然有些情况下我测试了失败场景,但我并没有完全按照这个答案所建议的方式测试它们(
我按照下面代码中显示的方式对其进行了测试。答案是建议您在测试方法签名上使用 "throws Exception",因为如果它实际上引发了您不期望的异常,它将无法通过测试。但是,无论有没有那段代码,我都尝试过,但都以同样的方式失败了。 上面提供的答案也通过使用 "rule" 来进行这种测试,我没有使用过,因为我需要的一切都在我的 try catch 块中,并且实例化是在 @Before 中完成的方法。
@Test
public void testMethod() {
try{
//code that will throw exception
fail("Exception was not thrown");
} catch (/* types of exceptions */) {
//my asserts
}
}
我所追求的是哪种方法被认为是 "best practice" 及其背后的原因。
@Test
注释的 expected
属性用于定义检查是否引发特定异常的测试用例。或者,还有用于更具体控制的 @Rules
注释和有点过时的 "try-catch" 习语。有关示例,请参阅 this and the junit wiki。
@Test(expected = IllegalArgumentException.class)
我个人使用 assertThrows 并将结果分配给 Throwable,这样我就可以检查消息。 这样做的原因是,例如,当我需要检查 return IllegalArgument 的验证时,我可以检查消息是否是该字段的预期消息。
@Test
public void testSomething_shouldThrowException() {
String expectedMessage = "Exception running the method";
Throwable exception = Assertions.assertThrows(YourException.class, ()
-> {
bean.doSomething(dummyRequest);
});
Assert.assertEquals(expectedMessage, exception.getMessage());
}
因为这是用 JUnit4 标记的,所以我更喜欢使用 @Test 注释的预期属性
@Test(expected = NullPointerException.class)
但是,如果您需要检查抛出的异常的更多属性,您可以使用 ExpectedException,它非常强大:
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void whenExceptionThrown_thenRuleIsApplied() {
exceptionRule.expect(NumberFormatException.class);
exceptionRule.expectMessage("For input string");
Integer.parseInt("1a");
}
不过,我建议使用 JUnit 5,您可以在其中使用 Java 8 构造,例如传递 Lambda 进行检查,这使您的代码非常明确和简洁。
JUnit 4 和 JUnit 5 的好文章:https://www.baeldung.com/junit-assert-exception