使用 JUnit 4 测试自定义异常的错误代码
Test the error code of a custom exception with JUnit 4
我想测试异常的return代码。这是我的生产代码:
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));
}
这就是您所需要的:
- 您不想期待那个特定的异常,因为您想要检查它的某些属性
- 您知道您想要进入那个特定的捕获块;因此,当调用没有抛出
时,你就失败了
- 您不需要任何其他检查 - 当该方法抛出任何其他异常时,JUnit 无论如何都会将其报告为错误
只要 thrown.expect
过载接收 Matcher
,您就可以使用 hamcres 匹配器检查它
thrown.expect(CombinableMatcher.both(
CoreMatchers.is(CoreMatchers.instanceOf(MyExceptionClass.class)))
.and(Matchers.hasProperty("errorCode", CoreMatchers.is(123))));
请注意,您需要将 hamcrest 匹配器添加到您的依赖项中。 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();
}
}
我想测试异常的return代码。这是我的生产代码:
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));
}
这就是您所需要的:
- 您不想期待那个特定的异常,因为您想要检查它的某些属性
- 您知道您想要进入那个特定的捕获块;因此,当调用没有抛出 时,你就失败了
- 您不需要任何其他检查 - 当该方法抛出任何其他异常时,JUnit 无论如何都会将其报告为错误
只要 thrown.expect
过载接收 Matcher
thrown.expect(CombinableMatcher.both(
CoreMatchers.is(CoreMatchers.instanceOf(MyExceptionClass.class)))
.and(Matchers.hasProperty("errorCode", CoreMatchers.is(123))));
请注意,您需要将 hamcrest 匹配器添加到您的依赖项中。 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();
}
}