我想测试异常的返回代码。这是我的生产代码:
class A {
try {
something...
}
catch (Exception e)
{
throw new MyExceptionClass(INTERNAL_ERROR_CODE, e);
}
}
以及相应的例外:
class MyExceptionClass extends ... {
private errorCode;
public MyExceptionClass(int errorCode){
this.errorCode = errorCode;
}
public getErrorCode(){
return this.errorCode;
}
}
我的单元测试:
public class AUnitTests{
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test (expected = MyExceptionClass.class,
public void whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode() throws Exception {
thrown.expect(MyExceptionClass.class);
??? expected return code INTERNAL_ERROR_CODE ???
something();
}
}
简单:
@Test
public void whenSerialNumberIsEmpty_shouldThrowSerialNumberInvalid() throws Exception {
try{
whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode();
fail("should have thrown");
}
catch (MyExceptionClass e){
assertThat(e.getCode(), is(MyExceptionClass.INTERNAL_ERROR_CODE));
}
这就是您在这里所需要的:
- 您不希望期望该特定异常,因为您想检查它的某些属性
- 你知道你想输入那个特定的 catch 块;因此当调用没有抛出时,你只会失败。
- 你不需要任何其他检查 - 当该方法抛出任何其他异常时,JUnit 无论如何都会将其报告为错误
thrown.expect
过载以接收Matcher
,您就可以使用 hamcres 匹配器检查它
thrown.expect(CombinableMatcher.both(
CoreMatchers.is(CoreMatchers.instanceOf(MyExceptionClass.class)))
.and(Matchers.hasProperty("errorCode", CoreMatchers.is(123))));
请注意,您需要将仓鼠匹配器添加到依赖项中。JUnit 中包含的核心匹配是不够的。
或者,如果您不想使用 CombinableMatcher:
thrown.expect(CoreMatchers.instanceOf(MyExceptionClass.class));
thrown.expect(Matchers.hasProperty("errorCode", CoreMatchers.is(123));
此外,您不需要(expected = MyExceptionClass.class)
声明即可进行@Test
注释
扩展 Sergii 的答案,您可以通过编写自定义匹配器来进一步清理它。
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class CustomMatcher extends TypeSafeMatcher<CustomException> {
public static CustomMatcher hasCode(String item) {
return new CustomMatcher(item);
}
private String foundErrorCode;
private final String expectedErrorCode;
private CustomMatcher(String expectedErrorCode) {
this.expectedErrorCode = expectedErrorCode;
}
@Override
protected boolean matchesSafely(final CustomException exception) {
foundErrorCode = exception.getErrorCode();
return foundErrorCode.equalsIgnoreCase(expectedErrorCode);
}
@Override
public void describeTo(Description description) {
description.appendValue(foundErrorCode)
.appendText(" was not found instead of ")
.appendValue(expectedErrorCode);
}
}
然后可以像这样检查错误代码:
import org.junit.rules.ExpectedException;
public class MyObjTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void someMethodThatThrowsCustomException() {
thrown.expect(CustomException.class);
thrown.expect(CustomMatcher.hasCode("110501"));
MyObj obj = new MyObj();
obj.methodThatThrowsCustomException();
}
}
参考: https://dzone.com/articles/testing-custom-exceptions