如果抛出JUnit ExpectedException后如何继续测试?

我已经使用ExpectedExceptionfunction设置了一些JUnit(4.12)测试,我希望测试在预期的exception之后继续。 但我从来没有看到日志’3’,因为执行似乎在exception后停止,如果捕获事件?

这实际上是可能的,怎么样?

@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"); } 

你不能这样做,当抛出exception时,它会抛出真实的ExpectedException规则。

如果你真的想要这种行为,你可以回到“旧学校”模式:

 try { userService.createUser("toto1"); Assert.fail("expecting some AlreadyExistsException here") } catch (AlreadyExistsException e) { // ignore } log.info("3"); 

但我不打扰一些日志。

这个SO解决方案似乎做了你想要做的事情: JUnit继续在预期的exception之后断言

我自己也在想类似的东西。 要继续测试,您必须自己在测试中捕获exception。 这个解决方案显示了一种优雅的方式。

注意:如果您制定规则以期望exception(就像您所做的那样),则只要抛出该exception,测试就会返回成功。 参考: http : //junit.org/javadoc/latest/org/junit/rules/ExpectedException.html

首先,你的测试没有测试一件事。 它在不同的条件下测试“userExists”和“createUser”,即不同的场景。 这被称为AssertionRoulette。 你不需要黑客继续记录“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"); } 

如果你不想为那些有很多选项抛出预期exception的东西添加很多类似的测试方法,并希望validation它实际上是在单个unit testing中抛出所有所需的情况,那么我会建议这个(不太漂亮)有用的架构:

 @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); } } 

也可以迭代一些预先准备好的列表的项目(甚至执行函数),而不是使用硬编码整数的switch-case。

Interesting Posts