java - 如何创建自定义“ExpectedException”junit 规则?
问题描述
我需要创建一个规则来检查自定义消息的异常。下面是我的尝试,但这并不完全正确,因为我只是使用标准“ExpectedException”中的方法。怎么做才对?
public class CustomExpectedExceptionRule implements TestRule {
private final ExpectedException delegate = ExpectedException.none();
public static CustomExpectedExceptionRule none() {
return new CustomExpectedExceptionRule();
}
private CustomExpectedExceptionRule() {
}
public void expect(Class<? extends Throwable> type) {
delegate.expect(type);
}
public void expectMessage(String message) {
delegate.expectMessage(message);
}
@Override
public Statement apply(Statement base, Description description) {
return delegate.apply(base, description);
}
现在我正在尝试这样的事情:
private final ExpectedException expectedException = ExpectedException.none();
private Object exception;
private String expectedMessage;
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
expectedException.expect((Class<? extends Throwable>) exception);
expectedException.expectMessage(expectedMessage);
base.evaluate();
}
};
}
public void expectedMessage(String expectedMessage) {
this.expectedMessage = expectedMessage;
}
public void expectedException(Object exception) {
this.exception = exception;
}
但是这个测试在抛出异常没有通过的地方不起作用,尽管这里的所有字段都通过了。如何以正确的形式重新制作它?
解决方案
据我了解要求,在您的测试中,您需要:
public class MyTest {
@Rule
ExpectedException expExc = ExpectedException.none();
@Test
public void throwsNothing() {
// "normal tests" not affected.
}
@Test
public void throwsExceptionWithSpecificTypeAndMessage() {
expExc.expect(MyCustomException.class);
expExc.expectMessage("substring, that passes test");// other matchers possible
// do something that (is expected to) raise(s)
// MyCustomException("substring, that passes test").
}
}
..whereMyCustomException.class
是一个自定义异常类(继承层次结构中的最低可能,您想要“传递”),以及您想要“传递”substring, that passes test
的消息(部分)。
引入定制TestRule
可以节省您的时间1 line/Test
。在这种简单的情况下,我建议您不要实现接口,而是扩展ExternalResource
(参见此处)):
class CustomExpectedException extends ExternalResource /*implements (!) TestRule*/ {
private ExpectedException expExc = ExpectedException.none();
/* Parameterize the message and also the class, if it fits your needs,
* alternatively && additionally implement defaults/constants/more methods.*/
public void myExpect(String substr) {
expExc.expect(MyCustomException.class);
expExc.expectMessage(substr);// other matchers possible
}
}
...然后像这样使用它:
public class MyTest {
@Rule
CustomExpectedException expExc = new CustomExpectedException();
...
@Test
public void throwsExceptionWithSpecificTypeAndMessage() {
expExc.myExpect("substring, that passes test");
// do something...
}
}
无规则的方法(见此处):
public class MyTest {
@Test
public void throwsExceptionWithSpecificTypeAndMessage() {
try { // !
// do something ...
// after that, fail the test:
org.junit.Assert.fail("expected exception!");
} catch (Exception exc) { // ! here i would recommend "the highest possible Exception" (in inheritance hierarchy) ...even better <code>Throwable</code>.
// this code can be moved to a (static) util method:
if (exc instanceof MyCustomException) {
// make assertions on ((MyCustomException) exc).getMessage();
} else {
org.junit.Assert.fail("UNexpected exception!");
// or rethrow:
// throw exc;
}
}
}
}
推荐阅读
- typescript - 提取内部通用类型的联合返回未知
- reactjs - 从 api 反应钩子中删除城市
- fortran - Fortran 管理本地数组内存
- javascript - 在 Axios 请求后向数组中的对象添加属性
- android - 如何将小部件带到 ListViewBuilder 的下一行?扑
- angular - 路由在本地工作,不在服务器上工作,即使 href 设置为服务器目标文件夹
- puppeteer - Puppeteer:打开隐身上下文时使用第一个新页面
- python - 如何对数据框中列表中的项目进行值计数
- google-play - Google Play 控制台从发布概览中删除应用
- graphql - Gatsby / GraphQL - 从外部 API 获取数据。设置 gatsby-node.js 但 SyntaxError: Unexpected token 'export'