web-dev-qa-db-ja.com

スローされた場合、JUnit ExpectedExceptionの後にテストを続行するにはどうすればよいですか?

ExpectedException機能を使用して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");
}
16
Deathtiny

あなたはそれを行うことができません、例外がスローされたとき、それは実際のExpectedExceptionルールのためにスローされます。

この種の動作が本当に必要な場合は、「古い学校」のパターンに戻ることができます。

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

log.info("3");

しかし、私はいくつかのログを気にしません。

14
user180100

これはSOソリューションがあなたのやりたいことをしているようです: JUnitは予期された例外の後で事を主張し続けます

私自身も似たようなことを考えていました。テストを続行するには、テストで例外を自分でキャッチする必要があります。このソリューションは、そのエレガントな方法を示しています。

注:例外を予期するようにルールを作成した場合(そうしたように)、その例外がスローされるとすぐにテストは成功を返します。リファレンス: http://junit.org/javadoc/latest/org/junit/rules/ExpectedException.html

3
Victor Silva

予想される例外をスローするための多くのオプションがある何かに対して同様のテストメソッドを多数追加したくない場合、および単一ユニット内の望ましいケースのallが実際にスローされることを確認する場合-test代わりに、これは(多分そうではないかもしれませんが)役立つスキーマです。

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

また、ハードコードされた整数でスイッチケースの代わりに、いくつかの事前に準備されたリストの項目を反復(および関数を実行)することもできます。

2

まず第一に、あなたのテストは一つのことをテストしません。 「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");    
}
1
thepacker