栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

测试失败时记录异常的最佳方法(例如,使用junit规则)

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

测试失败时记录异常的最佳方法(例如,使用junit规则)

您需要扩展TestRule,尤其是apply()。例如,查看org.junit.rules.ExternalResource和org.junit.rules.TemporaryFolder。

ExternalResource看起来像这样:

public abstract class ExternalResource implements TestRule {    public Statement apply(Statement base, Description description) {        return statement(base);    }    private Statement statement(final Statement base) {        return new Statement() { @Override public void evaluate() throws Throwable {     before();     try {         base.evaluate();     } finally {         after();     } }        };    }        protected void before() throws Throwable {        // do nothing    }        protected void after() {        // do nothing    }}

然后,TemporaryFolder对此进行扩展,并实现before()和after()。

public class TemporaryFolder extends ExternalResource {    private File folder;    @Override    protected void before() throws Throwable {        // create the folder    }    @Override    protected void after() {        // delete the folder    }

因此,before在testMethod之前被调用,after在finally中被调用,但是您可以捕获并记录任何Exception,例如:

    private Statement statement(final Statement base) {        return new Statement() { @Override public void evaluate() throws Throwable {     before();     try {         base.evaluate();     } catch (Exception e) {         log.error("caught Exception", e);     } finally {         after();     } }        };    }

编辑:以下工作:

public class SoTest {    public class ExceptionLoggingRule implements TestRule {        public Statement apply(Statement base, Description description) { return statement(base);        }        private Statement statement(final Statement base) { return new Statement() {     @Override     public void evaluate() throws Throwable {         try {  base.evaluate();         } catch (Exception e) {  System.out.println("caught an exception");  e.printStackTrace(System.out);  throw e;         }     } };        }    }    @Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();    @Rule public ExpectedException expectedException = ExpectedException.none();    @Test    public void testMe() throws Exception {        expectedException.expect(IOException.class);        throw new IOException("here we are");    }}

测试通过,您将获得以下输出:

caught an exceptionjava.io.IOException: here we are    at uk.co.farwell.junit.SoTest.testMe(SoTest.java:40)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)...

规则的应用顺序是ExpectedException,它调用ExceptionLoggingRule,后者调用testMe方法。ExceptionLoggingRule捕获异常,将其记录并重新抛出,然后由ExpectedException处理。

如果只想记录意外的异常,只需切换规则的声明顺序即可:

    @Rule public ExpectedException expectedException = ExpectedException.none();    @Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();

这样,将首先应用ExpectedException(即嵌套在exceptionLoggingRule中),并且仅重新引发意外的异常。此外,如果预期某些异常但未发生任何异常,则ExpectedException将抛出一个AssertionError,该异常也会被记录。

不能保证此评估顺序,但是除非您使用的是非常不同的JVM,或在Test类之间继承,否则它几乎不可能改变。

如果评估顺序很重要,那么您始终可以将一个规则传递给另一个规则进行评估。

编辑:使用最近发布的Junit 4.10,您可以使用@RuleChain正确地链接规则:

public static class UseRuleChain {   @Rule   public TestRule chain= RuleChain    .outerRule(new LoggingRule("outer rule")    .around(new LoggingRule("middle rule")    .around(new LoggingRule("inner rule");   @Test   public void example() {assertTrue(true);   }}

写日志

starting outer rulestarting middle rulestarting inner rulefinished inner rulefinished middle rulefinished outer rule


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/574396.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号