【问题标题】:How can I test several exceptions within one test using an ExpectedException Rule?如何使用 ExpectedException 规则在一个测试中测试多个异常?
【发布时间】:2013-07-17 07:38:30
【问题描述】:

有一个关于 junit 的 ExpectedException 规则使用的问题:

这里建议:junit ExpectedException Rule 从 junit 4.7 开始,可以测试这样的异常(这比 @Test(expected=Exception.class) 要好得多):

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

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

现在我需要在一个测试方法中测试几个异常,并在运行以下测试后得到一个绿色条,因此认为每个测试都通过了。

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

但是过了一会儿,我意识到测试方法在第一次检查通过后就退出了。这至少可以说是模棱两可的。在junit 3中,这很容易实现...... 所以这是我的问题:

如何使用 ExpectedException Rule 在一个测试中测试多个异常?

【问题讨论】:

  • 你仍然可以使用 Junit 3 的方式,但是不可能使用 @Test(expected) 和 ExpectedException。
  • 还不错。通常最好每次测试都测试一件事。如果你在同一个测试中测试一个列表的大小和内容,比如 notNull,这是可以的,但不要在一个测试中测试两个概念上不同的东西。它的可读性较差。如果您每次测试测试一件事,您可以使用方法名称来描述您正在测试的内容,而不是“testException”

标签: java unit-testing junit junit4 expected-exception


【解决方案1】:

简短的回答:你不能。

如果对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();
}

如果你真的想要一个而且只有一个测试,你可以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
}

不过,这很快就会变得非常混乱,如果第一个期望失败,您将看不到是否还有其他失败,这在故障排除时可能会很烦人。

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 2021-09-25
    • 2019-07-12
    • 2010-11-27
    相关资源
    最近更新 更多