【问题标题】:Can JUnit assertions be called from a method not annotated with @Test? [closed]可以从未使用 @Test 注释的方法调用 JUnit 断言吗? [关闭]
【发布时间】:2025-11-30 23:00:01
【问题描述】:

如果我有以下课程:

public class MyTest
{
   @Test
   public void testSomething()
   {
     Something myData = new Something();
     testAccordingToData(myData);
   }


   @Test
   public void testSomethingElse()
   {
     Something myOtherData = new Something("something else");
     testAccordingToData(myOtherData);
   }

   private void testAccordingToData(Something someData)
   {
     assertTrue(somedata.someField);
     assertEquals(someData.someField, someData.someOtherField);
     //and various other assertions based on someData
   }
}

testAccordingToData() 中的断言会正常工作,还是只能从带有 @Test 注释的方法中调用断言?

【问题讨论】:

  • 你尝试的时候发生了什么?
  • 如果你能自己解决非常简单的问题,你会更聪明。通过这种方式,您可以在几秒钟内同时权衡许多考虑因素。
  • @PeterLawrey 我同意,但这并不是一个非常简单的问题。可能适合有 JUnit 经验的人,是的,但不适合刚接触 JUnit 的人。
  • 你不可能了解每个库以及它的作用,但如果你能阅读它的代码,你总是可以足够快地完成它。
  • 你是说写一个包含public static void main(String[] args){assertTrue(false);}的课程会花费你几个小时吗?我现在明白你之前关于成为一名高效的程序员的评论了。

标签: java unit-testing junit


【解决方案1】:

junit“断言”只是简单的方法调用。可以从任何地方调用它们。

【讨论】:

  • 我明白了。但是,如果我有 5 个断言,并且如果断言 1-2 通过但断言 3 失败,那么断言 4 和 5 似乎根本不会被调用。如果它们是简单的方法调用,会发生什么?
  • @ClickUpvote - 失败的断言会引发异常。
  • 我明白了。谢谢!我发现它的工作原理很神秘。
  • @ClickUpvote Assert 类是通过阅读理解的最简单的类之一。在许多情况下,它的方法只有一到三行和十几行文档。
  • @jtahlborn 一个失败的断言不会抛出一个Exception;它抛出一个Error。它们不是一回事。
【解决方案2】:

这是 Assert 中最复杂的链。您可以看到它与注释无关,它会抛出一个 AssertionError ,这并不奇怪,因为这是在断言失败时所做的。

static public void assertEquals(String message, Object expected,
                                Object actual) {
    if (equalsRegardingNull(expected, actual)) {
        return;
    } else if (expected instanceof String && actual instanceof String) {
        String cleanMessage = message == null ? "" : message;
        throw new ComparisonFailure(cleanMessage, (String) expected,
                (String) actual);
    } else {
        failNotEquals(message, expected, actual);
    }
}

检查

private static boolean equalsRegardingNull(Object expected, Object actual) {
    if (expected == null) {
        return actual == null;
    }

    return isEquals(expected, actual);
}

失败时调用

static private void failNotEquals(String message, Object expected,
                                  Object actual) {
    fail(format(message, expected, actual));
}

哪个调用

static public void fail(String message) {
    if (message == null) {
        throw new AssertionError();
    }
    throw new AssertionError(message);
}

【讨论】:

    【解决方案3】:

    创建自定义断言方法并不常见,但通常是明智的。通常将方法命名为assertFoo

    如今,人们可以创建自定义 Hamcrest 匹配器。

    最后,您在上面评论说希望查看所有失败断言的结果。在这种情况下,JUnit 4.8 及更高版本为您提供了解决方案。看ErrorCollector@Rule

    【讨论】: