22

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

4 に答える 4

18

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

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

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

log.info("3");

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

于 2016-03-06T22:06:50.470 に答える
3

この SO ソリューションは、あなたがやりたいことをしているようです: JUnit continue to assert things after expected exception

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

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

于 2016-03-06T22:08:55.003 に答える
2

予想される例外をスローする多くのオプションがあるものに多くの同様のテストメソッドを追加したくない場合、代わりに単一の単体テスト内で必要なすべてのケースで実際にスローされることを確認したい場合は、この(かなりではないかもしれませんが)役立つスキーマを提案してください:

@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 の代わりに、事前に準備されたリストの項目を反復する (さらには関数を実行する) こともできます。

于 2016-10-10T08:02:35.290 に答える
1

まず第一に、あなたのテストは一つのことをテストしません。「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");    
}
于 2016-03-06T22:09:40.807 に答える