JUnit中是否有一种方法可以在@After注释方法中检测测试用例中是否存在测试失败或错误?
一个丑陋的解决方案是这样的:
boolean withoutFailure = false;
@Test
void test() {
...
asserts...
withoutFailure = true;
}
@After
public void tearDown() {
if(!withoutFailuere) {
this.dontReuseTestenvironmentForNextTest();
}
}
Run Code Online (Sandbox Code Playgroud)
这很难看,因为需要在测试代码中处理"基础设施"(withoutFailure标志).
我希望有一些东西可以在@After方法中获得测试状态!?
dsa*_*aff 10
如果您有幸使用JUnit 4.9或更高版本,TestWatcher将完全按照您的要求进行操作.
分享和享受!
我扩展了 dsaff 的答案,以解决TestRule无法执行在 test-method 和 after-method 执行之间截取的某些代码的问题。因此,MethodRule不能使用简单的规则来提供在带@After注释的方法中使用的成功标志。
我的想法是一个黑客!无论如何,它是使用TestRule(extends TestWatcher)。ATestRule将获得有关测试失败或成功的知识。TestRule然后我将扫描类中所有用我的新AfterHack注释注释的方法,并使用成功标志调用该方法。
AfterHack 注解
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
public @interface AfterHack {}
Run Code Online (Sandbox Code Playgroud)
AfterHackRule
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class AfterHackRule extends TestWatcher {
private Object testClassInstance;
public AfterHackRule(final Object testClassInstance) {
this.testClassInstance = testClassInstance;
}
protected void succeeded(Description description) {
invokeAfterHackMethods(true);
}
protected void failed(Throwable e, Description description) {
invokeAfterHackMethods(false);
}
public void invokeAfterHackMethods(boolean successFlag) {
for (Method afterHackMethod :
this.getAfterHackMethods(this.testClassInstance.getClass())) {
try {
afterHackMethod.invoke(this.testClassInstance, successFlag);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
throw new RuntimeException("error while invoking afterHackMethod "
+ afterHackMethod);
}
}
}
private List<Method> getAfterHackMethods(Class<?> testClass) {
List<Method> results = new ArrayList<>();
for (Method method : testClass.getMethods()) {
if (method.isAnnotationPresent(AfterHack.class)) {
results.add(method);
}
}
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
public class DemoTest {
@Rule
public AfterHackRule afterHackRule = new AfterHackRule(this);
@AfterHack
public void after(boolean success) {
System.out.println("afterHack:" + success);
}
@Test
public void demofails() {
Assert.fail();
}
@Test
public void demoSucceeds() {}
}
Run Code Online (Sandbox Code Playgroud)
顺便提一句:
@看