我在一个包含许多嵌入错误代码的“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注释)
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);
}
你觉得“干净”吗?你认为可以改善吗?你觉得它太重和/或没用吗?我的主要目标是在我们的开发团队中统一测试异常。(当然还有因式分解代码)
感谢阅读!
JUnitExpectedException
规则
怎么样?
首先,在测试类的顶部声明规则
:
@Rule
public final ExpectedException ee = ExpectedException.none();
然后,在测试方法中,您可以声明可以期待异常
:
@Test
public void testStuff() {
ee.expect(IllegalArgumentException.class);
ee.expectMessage("My Exception text");
}
@Test
public void testStuff() {
ee.expect(IllegalArgumentException.class);
ee.expectMessage(containsString("error"));
ee.expect(hasProperty("errorCode", is(7)));
}
public class ErrorCodeMatcher extends BaseMatcher<Throwable> {
private final int expectedErrorCode;
public ErrorCodeMatcher(int expectedErrorCode) {
this.expectedErrorCode = expectedErrorCode;
}
@Override
public boolean matches(Object o) {
return ((BusinessZipException) o).getErrorCode() == expectedErrorCode;
}
@Override
public void describeTo(Description d) {
d.appendText("Expected error code was" + expectedErrorCode);
}
}
ee.expect(new ErrorCodeMatcher(7));
使用static
工厂方法和static
导入,这可以变得非常干净:
ee.expect(exceptionWithErrorCode(7));
如果您有一个公共的接口
,它用getErrorCode()
方法定义业务异常
,例如callErrorAwareException
,那么您可以扩展TypeSafeMatcher
类,以创建稍微干净一点的代码:
public class ErrorCodeMatcher<T extends Exception & ErrorAwareException> extends TypeSafeMatcher<T> {
public static <E extends Exception & ErrorAwareException> ErrorCodeMatcher<E> exceptionWithErrorCode(final int expectedErrorCode) {
return new ErrorCodeMatcher<E>(expectedErrorCode);
}
private final int expectedErrorCode;
public ErrorCodeMatcher(int expectedErrorCode) {
this.expectedErrorCode = expectedErrorCode;
}
@Override
protected boolean matchesSafely(final T t) {
return t.getErrorCode() == expectedErrorCode;
}
@Override
public void describeTo(Description d) {
d.appendText("Expected error code was" + expectedErrorCode);
}
}
请注意,如果您确实选择使用hamcrest,那么请确保在项目中包含junit-dep
而不是纯junit
,否则hamcrest类将与junit
中包含的hamcrest类冲突。在maven中,如下所示:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
我构建了一个有3个属性的帐户类:余额、所有者、acctNo。帐户类有2个构造函数,一个接受3个属性,一个不接受数据。帐户类有设置和获取方法以及存款和取款方法。 我还构建了一个类,该类从类扩展而来。将此类修改为类后,取款方法或此方法尝试将余额设置为零以下,将抛出。 JUnit测试人员修改测试方法,将尝试提取超过当前余额的可用,所以做测试方法。我需要修改JUnit测试透支帐户,以便它捕获异常,并捕获。
问题内容: 我真的是java的新手。 我正在构造函数上运行一些JUnit测试。构造函数是这样的:如果为其参数之一赋予null或空字符串,则应该抛出异常。 当我在JUnit中使用null或空字符串参数测试此构造函数时,即使我几乎100%确信将此类参数传递给它时,构造函数方法确实会引发异常,我也会看到一条红色的条。 如果该方法以预期的方式引发异常,则JUnit中是否应该没有绿色的条形?还是当异常抛出按
问题内容: 编辑:目前没有JUnit 4。 嗨,您好, 我对使用JUnit进行“智能”异常测试有疑问。目前,我这样做是这样的: 如您所见,对于每个应该引发异常的函数,我都需要一个try / catch块。似乎不是执行此操作的好方法-还是没有可能减少try / catch的使用? 问题答案: 我建议您需要分解为多个单独的测试。各个try / catch块似乎彼此非常独立。您可能还希望将通用初始化逻辑
我应该如何测试异常?我可以mock connector并且我可以赋予它抛出异常的行为,但是我不明白下一步该怎么做。
问题内容: 我有一个尝试获取某些文件的简单方法。我想测试文件何时不存在,这就是我的问题所在。测试不断失败。 该方法类似于: 在测试中,我尝试了两种单独的解决方案,但均未成功。 使用SO解决方案中建议的新样式 public ExpectedException exception = ExpectedException.none(); @Test public void testPopulateCon
我试图创建一个测试来验证我的代码(见下面的伪代码)是否正确捕获异常。我知道JUnit能够测试代码是否用以下代码抛出异常: 然而,我正在测试的软件的原始代码捕获了这个异常并打印了一条消息 JUnit是否有办法验证此消息?或者我应该改变一下我的流行语? 注:我已阅读,我应使用以下内容: 但是程序崩溃,因为它无法识别对象。 我尝试测试的方法的伪代码(出于隐私原因,不要发布确切的内容):