是否可以使用 JUnit Rule ExpectedException 访问异常 "catched" 的实例?
Is it possible to access instance of exception "catched" with JUnit Rule ExpectedException?
假设在一个测试中是:
@Rule
public ExpectedException thrown = ExpectedException.none();
一些测试包含:
thrown.expect(SomeNastyException.class);
现在如果有需要检查这个SomeNastyException
更详细的方法是什么?
当然可以不使用 ExcpectedException
并使用 try/catch 包装调用,然后以任何需要的方式检查异常但现在的问题是可以用 ExpectedException
来完成,比如:
assertEquals("42", thrown.getException().getUniversalAnswerToEverything());
该规则中有一个不太专业的 expect
方法版本,它接受 Hamcrest 的匹配器:
只要有一个 Matcher
实现,此方法将允许您对抛出的异常断言几乎所有内容。
例如,对于您的情况,它看起来像这样:
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
....
exceptions.expect(hasProperty("UniversalAnswerToEverything", is(42)));
Hamcrest 有一个非常灵活的匹配器模型,因此如果您对库中包含的内容不满意,也可以轻松编写自己的匹配器模型。
您可以使用 hasProperty hamcrest Matcher。如果您的 SomeNastyException 不符合 java bean 协议,您可以为您的异常创建一个自定义的 hamcrest 匹配器:
package Whosebug.q59946794;
import org.hamcrest.Description;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.hamcrest.core.IsEqual;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.logging.Logger;
public class SomeNastyExceptionSpec {
private final static Logger logger = Logger.getLogger(SomeNastyExceptionSpec.class.getName());
public static class SomeNastyException extends Exception implements java.io.Serializable {
SomeNastyException(String message) { super(message);}
public Integer getUniversalAnswerToEverything() {return 42;}
}
public static Matcher<SomeNastyException> hasUniversalAnswerToEverythingFeature(final int expectedAnswer) {
return new FeatureMatcher<SomeNastyException, Integer>(
new IsEqual<Integer>(expectedAnswer),
"SomeNastyException actual answer",
"SomeNastyException expected answer"
) {
@Override
protected Integer featureValueOf(SomeNastyException actual) {
return actual.getUniversalAnswerToEverything();
}
};
}
public static Matcher<SomeNastyException> hasUniversalAnswerToEverything(final int expectedAnswer) {
return new TypeSafeMatcher<SomeNastyException>() {
@Override
protected void describeMismatchSafely(SomeNastyException e, Description description) {
description.appendText("was ").appendValue(e.getUniversalAnswerToEverything());
}
@Override
public void describeTo(Description description) {
description.appendText("SomeNastyException with answer ").appendValue(expectedAnswer);
}
@Override
protected boolean matchesSafely(SomeNastyException e) {
return e.getUniversalAnswerToEverything() == expectedAnswer;
}
};
}
@Rule(order = Integer.MAX_VALUE)
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws Exception {
thrown.expect(SomeNastyException.class);
thrown.expect(hasUniversalAnswerToEverything(42));
thrown.expect(hasUniversalAnswerToEverythingFeature(42));
thrown.expectMessage("always 42");
throw new SomeNastyException("always 42");
}
}
我的问题是在仍在使用 JUnit4 时提出的。最近迁移到 JUnit5,它正是我要找的东西,即 assertThrows
returns 抛出的异常。作为一个虚拟的例子:
@org.junit.jupiter.api.Test
void testThrows() {
Exception exception = assertThrows(NotAnswerableException.class, () -> {
throw new NotAnswerableException("please rephrase your question", param2, param3);
});
assertTrue(exception.getMessage().startsWith("please"));
assertEquals(param2, exception.getParam2());
}
假设在一个测试中是:
@Rule
public ExpectedException thrown = ExpectedException.none();
一些测试包含:
thrown.expect(SomeNastyException.class);
现在如果有需要检查这个SomeNastyException
更详细的方法是什么?
当然可以不使用 ExcpectedException
并使用 try/catch 包装调用,然后以任何需要的方式检查异常但现在的问题是可以用 ExpectedException
来完成,比如:
assertEquals("42", thrown.getException().getUniversalAnswerToEverything());
该规则中有一个不太专业的 expect
方法版本,它接受 Hamcrest 的匹配器:
只要有一个 Matcher
实现,此方法将允许您对抛出的异常断言几乎所有内容。
例如,对于您的情况,它看起来像这样:
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
....
exceptions.expect(hasProperty("UniversalAnswerToEverything", is(42)));
Hamcrest 有一个非常灵活的匹配器模型,因此如果您对库中包含的内容不满意,也可以轻松编写自己的匹配器模型。
您可以使用 hasProperty hamcrest Matcher。如果您的 SomeNastyException 不符合 java bean 协议,您可以为您的异常创建一个自定义的 hamcrest 匹配器:
package Whosebug.q59946794;
import org.hamcrest.Description;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.hamcrest.core.IsEqual;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.logging.Logger;
public class SomeNastyExceptionSpec {
private final static Logger logger = Logger.getLogger(SomeNastyExceptionSpec.class.getName());
public static class SomeNastyException extends Exception implements java.io.Serializable {
SomeNastyException(String message) { super(message);}
public Integer getUniversalAnswerToEverything() {return 42;}
}
public static Matcher<SomeNastyException> hasUniversalAnswerToEverythingFeature(final int expectedAnswer) {
return new FeatureMatcher<SomeNastyException, Integer>(
new IsEqual<Integer>(expectedAnswer),
"SomeNastyException actual answer",
"SomeNastyException expected answer"
) {
@Override
protected Integer featureValueOf(SomeNastyException actual) {
return actual.getUniversalAnswerToEverything();
}
};
}
public static Matcher<SomeNastyException> hasUniversalAnswerToEverything(final int expectedAnswer) {
return new TypeSafeMatcher<SomeNastyException>() {
@Override
protected void describeMismatchSafely(SomeNastyException e, Description description) {
description.appendText("was ").appendValue(e.getUniversalAnswerToEverything());
}
@Override
public void describeTo(Description description) {
description.appendText("SomeNastyException with answer ").appendValue(expectedAnswer);
}
@Override
protected boolean matchesSafely(SomeNastyException e) {
return e.getUniversalAnswerToEverything() == expectedAnswer;
}
};
}
@Rule(order = Integer.MAX_VALUE)
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws Exception {
thrown.expect(SomeNastyException.class);
thrown.expect(hasUniversalAnswerToEverything(42));
thrown.expect(hasUniversalAnswerToEverythingFeature(42));
thrown.expectMessage("always 42");
throw new SomeNastyException("always 42");
}
}
我的问题是在仍在使用 JUnit4 时提出的。最近迁移到 JUnit5,它正是我要找的东西,即 assertThrows
returns 抛出的异常。作为一个虚拟的例子:
@org.junit.jupiter.api.Test
void testThrows() {
Exception exception = assertThrows(NotAnswerableException.class, () -> {
throw new NotAnswerableException("please rephrase your question", param2, param3);
});
assertTrue(exception.getMessage().startsWith("please"));
assertEquals(param2, exception.getParam2());
}