【问题标题】:JUnit assertion to force a line to be executedJUnit 断言强制执行一行
【发布时间】:2015-04-30 09:36:19
【问题描述】:

是否有任何 junit 断言,我可以使用它强制执行一行?

例如:

doAnswer(new Answer<Void>() {
    @SuppressWarnings("unchecked")
    @Override
    public Void answer(final InvocationOnMock invocation) throws Throwable {
        Object[] arguments = invocation.getArguments();
        Map<String, String> fieldMapActual = (Map<String, String>) arguments[0];
        assertEquals(fieldMap, fieldMapActual);

        **assertFailIfThisLineIsNotExecuted();**

        return null;
    }
}).when(x).myMethod(xxx);

当我模拟 myMethod 的行为时,来自匿名内部类型的方法答案将在 myMethod 的运行时(而不是在 junit 测试的运行时)执行,如果 myMethod 将使用预期的值/参数调用。 为了断言该方法被调用,我必须另外定义一个验证(否则即使没有调用该方法,我的测试仍然会运行)。

verify(x).myMethod(xxx); 

如果我有机会在 answer 方法中写出像 assertFailIfThisLineIsNotExecuted 这样的东西,我就不必定义额外的验证。再说一遍,是否有任何 junit 断言,我可以用它强制执行一行?可以说与fail()相反,没有立即将方法定义为“成功”。

【问题讨论】:

  • 验证answer的处理结果就知道了。为什么你不能测试它的行为?
  • myMethod 是无效的,这里多用 doAnswer..
  • 你不应该模拟你正在测试的单元。如果您正在测试是否在特定情况下调用 myMethod(这就是您所说的“assertIfThisLineIsNotExecuted”,那么您实际上是在测试您的模拟行为
  • 换句话说,至少在 IMO,你不应该在 doAnswer 中包含 assert*
  • 在某些情况下,它使 %100 有意义。应该这样做。例如:akcasoy.wordpress.com/2015/04/09/the-power-of-thenanswer 用例 2

标签: java unit-testing junit mockito


【解决方案1】:

如果您想确保测试的某一行正在执行,请使用布尔标志:

 final boolean[] wasExecuted = { false };

 ...
     wasExecuted[0] = true;
 ...

 assertTrue("Some code wasn't executed", wasExecuted);

但我的直觉是,您正在尝试解决不同的问题。

verify 表示“必须调用此方法”。你是否嘲笑答案并不重要。所以这是你应该使用的方法。

我仅在由于某种原因无法创建模拟时才使用我的标志方法。如果发生这种情况,我会在我的测试代码中扩展被测类并添加标志。

标志相对于verify 的优势在于标志记录了我期望代码所在的位置(您可以让 IDE 搜索使用标志的所有位置)。 verify() 失败时不容易定位。

verify(x).myMethod(xxx); 应该是你想要的。它也表达了意图。

assertFailIfThisLineIsNotExecuted() 也将是一行代码(那么它如何比verify“更好”?),它不受 JUnit 支持,您必须编写代码才能获得良好的错误消息等.

【讨论】:

  • 我会为But my gut feeling is that you're trying to solve a different problem.投票+1
  • 使用标志很好,但你是对的..验证应该是正确的方法。当我都想模拟和验证时,我感到很不舒服,因为方法参数必须定义两次。我只是更喜欢在定义我的模拟时添加一个额外的参数,无论这个调用是可选的还是强制性的;所以我不必写验证。不幸的是,我们有 4-5 个参数的方法,当我们甚至不得不使用 ArgumentCaptor 等时,您可能会猜到验证本身可能包含 3 行或......
  • ArgumentCaptor 移动到辅助方法中,这样您就可以编写(foo(...), bar(...), baz(...))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-10
  • 1970-01-01
相关资源
最近更新 更多