Java:在JUnit assert*中使用日志记录器

7
我想在JUnit中做类似以下的事情:
assertTrue(logger.error("the condition is not true"), <a boolean condition>);

因此,错误消息将由记录器记录,其中记录器可以是例如commons或log4j。

但是,Junit断言不接受记录器参数,那么有没有办法实现这一点,或者我需要在try-catch中捕获assert并在catch块中记录错误消息?

3个回答

22
你可以使用JUnit的TestRule TestWatcher。一个TestRule在测试方法之前和之后执行代码(类似于@Before@After),但你可以访问更多信息,更重要的是,可以得到测试结果。一个TestWatcher定义了像succeeded()failed()starting()finished()这样的方法,你可以实现它们以获得通知事件。
下面的示例只是简单地打印出失败的测试和失败的断言。
public class TestWatcherTest {
  @Rule
  public TestWatcher testWatcher = new TestWatcher() {
    protected void failed(Throwable e, Description description) {
      System.out.println("" + description.getDisplayName() + " failed " + e.getMessage());
      super.failed(e, description);
    }

  };

  @Test
  public void test1() {
    Assert.assertEquals("hello world", 3, 4);
  }
}

你可以自行选择而非使用System.out.println()。这将产生以下输出:
test1(uk.co.farwell.junit.TestWatcherTest) failed hello world expected:<3> but was:<4>

请注意,断言失败是一种异常,因此您可以访问堆栈跟踪等信息。

正是我想要的。谢谢! - shrini1000
JUnit 的哪个版本引入了这个功能? - duffymo
2
TestWatcher在4.9中被引入,作为TestWatchman的替代品。而TestWatchman自身则是在4.7中被引入的。 TestWatchman是一个略微不同的东西,它使用MethodRule,而该规则现已过时。 - Matthew Farwell

3
我不会更改或扩展JUnit类。
更好的做法是使用try/catch和记录错误。
问题在于失败的Assert不一定是异常。
感觉你正在尝试将log4j变成已经存在的报告功能。我建议您研究Ant JUnit报告任务-它会给您一个漂亮的报告,比日志更有用。
更新:
您总是可以添加另一个log4j文件附加程序。让log4j将消息写入您选择的控制台和文件。如果我没错的话,您的代码完全不需要更改。

我想做的是控制JUnit断言的输出,以便我可以将其发送到某个数据库进行进一步分析。是否有一种使用Ant JUnit报告来实现这一点的方法? - shrini1000
@duffymo 失败的(junit)断言一个异常,具体来说是AssertionError。这就是JUnit的工作原理。 - Matthew Farwell
我在编写JUnit时从不捕获错误。我要么编写Assert以使其成功,要么在预期出现异常的情况下添加注释来说明。你可能是对的,JUnit在底层是这样工作的,但我不想强制遵循它的编码方式。 - duffymo
@duffymo 关于捕获错误,我也是一样,除非我正在测试它们。我只是想澄清JUnit在内部的工作方式。如果您执行失败的断言,则会停止测试方法的执行,因为已抛出AssertionError。 - Matthew Farwell
感谢澄清,Matthew。我想我们是一致的,除了捕获错误的部分。我的偏好是使用@expecting注释,但那更多是风格问题。非常感谢你在上面提到的新注释的观点。 - duffymo

2
最好使用这个。
if(!<condition>) {
logger.error("my message");
Assert.fail();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接