最近,在一次代码审查中,一位同事说“测试不应该有试试块”。他还向我指出了有关ExpectedException
的信息,并且我能够使用它来重写我正在对异常数据执行检查的一些测试。
然而,我遇到的情况是我不确定我是否可以消除try-catch。我正在为一个方法编写单元测试,该方法将抛出异常和,这将执行我需要使用JMockit验证的一些行为。假设测试中的代码包含类似
的内容try {
...code...
} catch (SomeException e) {
statusMessage.send("Failure", <parameters with some data>);
throw e;
}
JUnit测试目前看起来像
@Test
public void test() {
... set things up ...
try {
callTheMethod();
fail("No exception thrown");
} catch (Exception e) {
assertEquals(SomeException.class, e.getClass());
}
new Verifications() { {
statusMessage.send("Failure", <expected data>);
} }
}
我找不到摆脱try-catch的好方法。我个人认为没有问题,但如果我至少尝试摆脱它,我很可能抓住来自我的同事:) :) :)
fail
和assertEquals
不是必需的。如果有一种简单的方法可以告诉JUnit / JMockit简单地忽略来自callTheMethod()
的任何异常并继续,那就没关系了 - 我可以创建另一个测试来检查异常。
是否有一些JUnit或JMockit功能可以让我完成我想要做的事情?
[注意:编辑清楚我正在测试的行为是对模拟对象的调用,而不是静态方法调用。这与问题无关。]
答案 0 :(得分:2)
您的同事在一般意义上可能是正确的,使用try-catch
来测试您的异常处理比使用提供的ExpectedException
实用程序更不可取。但是,我并不认为该规则适用于您的案件;捕获异常,以便您可以验证其他事情是完全合理的。没有其他方法可以阻止传播AFAIK的异常。
答案 1 :(得分:1)
目前使用普通的JUnit,如果要在抛出断言后验证某些内容,则必须使用try-catch
。使用JUnit 4.13(尚未发布),您可以使用
expectThrows(Exception.class, () -> callTheMethod());
new Verifications() { {
statusMessage.send("Failure", <expected data>);
} }
作为替代方案,您可以使用Fishbowl's ignoreException。
ignoreException(() -> callTheMethod());
new Verifications() { {
statusMessage.send("Failure", <expected data>);
} }
完全披露:我是Fishbowl的作者。
答案 2 :(得分:-1)
根据API,我会说你可以这样做:
class AjbUnitTest
{
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void test()
{
... set things up ...
thrown.expect(SomeException.class)
callTheMethod(); / Preumably this throws SomeException
...
}
}
答案 3 :(得分:-2)
对于异常特定的断言AssertJ有一个很好的API:
@Test
public void testException() {
assertThatThrownBy(() -> { throw new Exception("error!") })
.isInstanceOf(Exception.class)
.hasMessageContaining("error");
}
基本上,你可以&#34;收集&#34;例外,不会中断测试执行。