Java 为意外异常断言该错误消息
我有这样的JUnit测试:Java 为意外异常断言该错误消息,java,junit,Java,Junit,我有这样的JUnit测试: @Test public void testNullCheck() { String res = someMethod(); assertThat("This is the someMethodTest", res, is(notNullValue())); } 如果someMethod引发异常,我将获得堆栈跟踪,但这是someMethodTest未打印为未调用的AssertTest。是否有一种优雅的JUnit/hamcrest方式来打印自定义错误消息?
@Test
public void testNullCheck() {
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}
如果someMethod引发异常,我将获得堆栈跟踪,但这是someMethodTest未打印为未调用的AssertTest。是否有一种优雅的JUnit/hamcrest方式来打印自定义错误消息?最终,我希望在参数化测试中打印测试失败的参数。注意,我不想测试特定的异常。这样做怎么样:
@Test
public void testNullCheck() {
try{
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}catch( Exception e /*or any especific exception*/ ){
fail("This is the someMethodTest Error " + e.getMessage() );
}
}
这样怎么样:
@Test
public void testNullCheck() {
try{
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}catch( Exception e /*or any especific exception*/ ){
fail("This is the someMethodTest Error " + e.getMessage() );
}
}
您可以创建自己的,以替换异常:
public class NiceExceptions implements TestRule {
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable t) {
throw new YourNiceException(t);
}
}
};
}
}
public class YourTest {
@Rule
public final TestRule niceExceptions = new NiceExceptions();
@Test
public void yourTest() {
...
}
}
您可以创建自己的,以替换异常:
public class NiceExceptions implements TestRule {
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable t) {
throw new YourNiceException(t);
}
}
};
}
}
public class YourTest {
@Rule
public final TestRule niceExceptions = new NiceExceptions();
@Test
public void yourTest() {
...
}
}
根据Stefan Birkner的建议,这就是我的想法。欢迎评论
package my.test;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class ExceptionCatcher implements TestRule {
String msg;
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (AssertionError e){
throw e;
} catch (Throwable t) {
msg = t.getMessage() + "; " + msg;
Throwable cause = t.getCause();
if (cause == null)
cause = t;
StackTraceElement[] stackTrace = cause.getStackTrace();
Throwable t1 = null;
try {
t1 = t.getClass().newInstance();
t1 = t.getClass().getDeclaredConstructor(String.class).newInstance(msg);
t1 = t.getClass().getDeclaredConstructor(String.class, Throwable.class).newInstance(msg, t);
t1.setStackTrace(stackTrace);
throw t1;
} catch (Throwable ignore) {
t1.setStackTrace(stackTrace);
throw t1;
}
}
}
};
}
public void setMsg(String msg) {
this.msg = msg;
}
}
在测试用例中:
@Rule
public final ExceptionCatcher catcher = new ExceptionCatcher();
@Before
public void setUp() throws Exception {
catcher.setMsg("....");
}
@Test
public void testNullCheck() {
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}
根据Stefan Birkner的建议,这就是我的想法。欢迎评论
package my.test;
import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class ExceptionCatcher implements TestRule {
String msg;
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssumptionViolatedException e) {
throw e;
} catch (AssertionError e){
throw e;
} catch (Throwable t) {
msg = t.getMessage() + "; " + msg;
Throwable cause = t.getCause();
if (cause == null)
cause = t;
StackTraceElement[] stackTrace = cause.getStackTrace();
Throwable t1 = null;
try {
t1 = t.getClass().newInstance();
t1 = t.getClass().getDeclaredConstructor(String.class).newInstance(msg);
t1 = t.getClass().getDeclaredConstructor(String.class, Throwable.class).newInstance(msg, t);
t1.setStackTrace(stackTrace);
throw t1;
} catch (Throwable ignore) {
t1.setStackTrace(stackTrace);
throw t1;
}
}
}
};
}
public void setMsg(String msg) {
this.msg = msg;
}
}
在测试用例中:
@Rule
public final ExceptionCatcher catcher = new ExceptionCatcher();
@Before
public void setUp() throws Exception {
catcher.setMsg("....");
}
@Test
public void testNullCheck() {
String res = someMethod();
assertThat("This is the someMethodTest", res, is(notNullValue()));
}
谢谢这正是我所希望的。玩了一会儿之后,我意识到我真正需要的是修改描述。有没有其他方法可以做到这一点?现在,我将另一个消息字段添加到NiceExceptions中,并在测试中通过@Before将其设置为所需的值。有点效果,但也许有更简单的。谢谢。这正是我所希望的。玩了一会儿之后,我意识到我真正需要的是修改描述。有没有其他方法可以做到这一点?现在,我将另一个消息字段添加到NiceExceptions中,并在测试中通过@Before将其设置为所需的值。有点效果,但也许有更简单的。谢谢,这或多或少也是我想到的。但是如果我想保留stacktrace,我必须添加更多无用的代码来掩盖实际的测试。谢谢,这或多或少也是我想到的。但是如果我想保留stacktrace,我必须添加更多无用的代码来掩盖实际的测试。