7

Got a question regarding the usage of junit's ExpectedException rule:

As suggested here: junit ExpectedException Rule starting from junit 4.7 one can test exceptions like this (which is much better then the @Test(expected=Exception.class)):

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void testFailuresOfClass() {
 Foo foo = new Foo();
 exception.expect(Exception.class);
 foo.doStuff();
}

Now I needed to test several exceptions in one test method and got a green bar after running the following test and thus thought every test passed.

@Test
public void testFailuresOfClass() {
 Foo foo = new Foo();

 exception.expect(IndexOutOfBoundsException.class);
 foo.doStuff();

 //this is not tested anymore and if the first passes everything looks fine
 exception.expect(NullPointerException.class);
 foo.doStuff(null);

 exception.expect(MyOwnException.class);
 foo.doStuff(null,"");

 exception.expect(DomainException.class);
 foo.doOtherStuff();
}

However after a while I realized that the testmethod is quit after the first check passes. This is ambiguous to say the least. In junit 3 this was easily possible... So here is my question:

How can I test several exceptions within one test using an ExpectedException Rule?

4

1 に答える 1

6

簡単な答え: できません。

最初の呼び出しfoo.doStuff()で例外がスローされた場合、 に到達することはありませんfoo.doStuff(null)。テストをいくつかに分割する必要があります (この些細なケースでは、 を使用しない単純な表記法に戻ることをお勧めしますExpectedException):

private Foo foo;

@Before 
public void setUp() {
 foo = new Foo();
}

@Test(expected = IndexOutOfBoundsException.class)
public void noArgsShouldFail() {
 foo.doStuff();
}

@Test(expected = NullPointerException.class)
public void nullArgShouldFail() {
 foo.doStuff(null);
}

@Test(expected = MyOwnException.class)
public void nullAndEmptyStringShouldFail() {
 foo.doStuff(null,"");
}

@Test(expected = DomainException.class)
public void doOtherStuffShouldFail() {
 foo.doOtherStuff();
}

本当に 1 つだけのテストが必要なfail場合は、エラーがスローされなければ、期待どおりのものをキャッチできます。

@Test
public void testFailuresOfClass() {
 Foo foo = new Foo();

 try {
    foo.doStuff();
    fail("doStuff() should not have succeeded");
 } catch (IndexOutOfBoundsException expected) {
    // This is what we want.
 }
 try {
    foo.doStuff(null);
    fail("doStuff(null) should not have succeeded");
 } catch (NullPointerException expected) {
    // This is what we want.
 }
 // etc for other failure modes
}

ただし、これは非常に急速に厄介になり、最初の期待が失敗した場合、他の何かが失敗したかどうかもわかりません。これは、トラブルシューティングの際に面倒になる可能性があります.

于 2013-07-18T11:34:41.467 に答える