我在一个项目中工作,其中包含许多嵌入了errorCode的“BusinessException” .
在每个单元测试异常中,我必须测试这些错误代码重复这种模式:
@Test
public void zipFileReaderCtorShouldThrowAnExceptionWithInexistingArchive() {
try {
zfr = new ZipFileReader("unexpected/path/to/file");
fail("'BusinessZipException' not throwed");
} catch (BusinessZipException e) {
assertThat("Unexpected error code", e.getErrorCode(), is(ErrorCode.FILE_NOT_FOUND));
} catch (Exception e) {
fail("Unexpected Exception: '" + e + "', expected: 'BusinessZipException'");
}
}
(由于错误代码测试,使用JUnit注释是不可能的)
我很无聊,特别是因为我必须在fail()的错误消息中复制/粘贴异常名称 .
所以,我写了一个Util类 . 我使用抽象类来处理异常断言测试 .
public abstract class TestExceptionUtil {
public void runAndExpectException(Class expectedException, String expectedErrorCode) {
String failUnexpectedExceptionMessage = "Unexpected exception. Expected is: '%s', but got: '%s'";
try {
codeToExecute();
fail("'" + expectedException.getName() + "' not throwed");
} catch (BusinessException e) {
if (e.getClass().equals(expectedException)) {
assertThat("Exception error code not expected", e.getErrorCode(), is(expectedErrorCode));
} else {
fail(String.format(failUnexpectedExceptionMessage, expectedException.getName(), e));
}
} catch (Exception e) {
fail(String.format(failUnexpectedExceptionMessage, expectedException.getName(), e));
}
}
abstract public void codeToExecute();
}
然后,客户端以这种方式使用它:
@Test
public void zipFileReaderCtorShouldThrowAnExceptionWithInexistingArchive() {
new TestExceptionUtil() {
@Override
public void codeToExecute() {
zfr = new ZipFileReader("unexpected/path/to/file");
}
}.runAndExpectException(BusinessTechnicalException.class, ErrorCode.FILE_NOT_FOUND);
}
你觉得它“干净”吗?你认为它可以改善吗?你认为它太沉重和/或没用吗?我的主要目标是在开发团队中统一测试异常 . (当然还有代码化代码)
谢谢阅读!
2 回答
JUnit怎么样ExpectedException Rule?
首先,在测试类的顶部声明
Rule
:然后在您的测试方法中,您可以声明您可以期待
Exception
:我认为这比你的方法更清晰 .
然后,您可以使用hamcrest Matcher来匹配
Exception
消息:hasProperty
Matcher
将为命名属性查找getter并检查它是否与第二个参数匹配 - 这是另一个Matcher
.你甚至可以实现自己的
Matcher
,在这种情况下你不需要依赖hamcrest:这将使用如下:
使用
static
工厂方法和static
导入,这可以变得非常干净:如果您有一个共同的
interface
用getErrorCode()
方法定义您的业务Exception
,比如称为ErrorAwareException
,那么您可以扩展TypeSafeMatcher<T>
类以创建稍微更清晰的代码:请注意,如果您确实选择使用hamcrest,那么请确保在项目中包含
junit-dep
而不是纯junit
,否则hamcrest类将与junit
中包含的hamcrest类冲突 . 在maven中,这看起来像这样:我想你实际上是在这里重新发明轮子 . 您可以使用
@Test
注释的expected
参数,这会导致测试方法成功抛出给定的异常 . 或者使用ExpectedException
规则基本相同,但具有更多功能 . 所以试试吧要么