我已经使用预期异常功能设置了一些JUnit(4.12)测试,我希望测试在预期异常后继续。但是我从来没有看到日志"3",因为执行似乎在异常后停止,如果捕获事件?
这真的可能吗,如何?
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void testUserAlreadyExists() throws Exception {
log.info("1");
// Create some users
userService.createUser("toto1");
userService.createUser("toto2");
userService.createUser("toto3");
Assert.assertTrue( userService.userExists("toto1") );
Assert.assertTrue( userService.userExists("toto2") );
Assert.assertTrue( userService.userExists("toto3") );
log.info("2");
// Try to create an existing user
exception.expect(AlreadyExistsException.class);
userService.createUser("toto1");
log.info("3");
}
这样做,当抛出异常时,无论是否ExpectedException
规则,它都会被抛出。
如果你真的想要这种行为,你可以回到"老派"模式:
try {
userService.createUser("toto1");
Assert.fail("expecting some AlreadyExistsException here")
} catch (AlreadyExistsException e) {
// ignore
}
log.info("3");
但我不会打扰一些日志。
这个 SO 解决方案似乎可以做你想做的事情: JUnit 在预期异常后继续断言事情
我自己也在想类似的事情。要继续测试,您必须自己在测试中捕获异常。此解决方案展示了一种优雅的实现方式。
注意:如果您将规则设置为预期异常(就像您所做的那样),则一旦引发该异常,测试将返回成功。参考: http://junit.org/javadoc/latest/org/junit/rules/ExpectedException.html
如果您不想为具有许多选项来抛出预期异常的东西添加很多类似的测试方法,并且想要验证它是否确实在单个单元测试中抛出所有所需的情况,我建议这个(也许不是很)有用的架构:
@Test
public void testThatSomethingExpectedlyFails() {
for (int i = 1; i <= 3; i++) {
try {
switch (i) {
case 1: // smth here throws the exception when configuration #1;
case 2: // smth here throws the exception when configuration #2;
case 3: // smth here throws the exception when configuration #3;
}
} catch (ExceptionThatIsExpected expected) {
continue;
} catch (Exception unexpected) {
/* the test must fail when an unexpected exception is thrown */
fail("The test has failed due to an unexpected exception: " + unexpected.getMessage()); // or just re-throw this exception
}
/* the test must fail when a case completes without the expected exception */
fail("No expected exception occurred at case " + i);
}
}
还可以迭代一些预先准备好的列表的项目(甚至执行函数),而不是使用硬编码整数的开关大小写。
首先,你的测试没有测试一件事。它在不同的条件下测试"userExists"和"createUser",也就是不同的场景。这称为断言轮盘赌。如果你要编写测试,你不需要黑客来继续记录"3",这些测试失败了正确的原因。
如果测试由于正确的原因而失败,您可以看到为什么它失败而不执行所有日志记录操作。Junit-Runner已经为您记录了日志。
@Test
public void testUserExists_UserCreatedUserNotExistent_expectTrue()
{
// Create some users
userService.createUser("toto1");
// Assert That user exists
Assert.assertTrue( userService.userExists("toto1") );
}
@Test
public void testCreateUser_UserAlreadyCreated_expectAlreadyExistsExceptionIsThrown()
{
// Create some users
userService.createUser("toto1");
// Try to create an existing user
exception.expect(AlreadyExistsException.class);
userService.createUser("toto1");
}