简体   繁体   English

同时使用junit断言和Mockito验证

[英]Using both junit assertions and mockito verification

I'm using Junit in conjunction with Mockito. 我将Junit与Mockito结合使用。 I used mockito's verify method + junit assertion to do complete verification. 我使用了Mockito的verify方法+ junit断言来完成验证。 Is this not desirable? 这是不可取的吗? Should we use one or the other but not both? 我们应该使用其中一个,但不能同时使用两者?

There's nothing wrong with using both. 两者都没错。

Mockito's verify is used to assert a method was called (with the expected arguments) on the given mock. Mockito的verify用于断言在给定模拟中调用了一个方法(带有预期的参数)。

JUnit's assertXYZ is used to assert that some result has the expected value. JUnit的assertXYZ用于断言某些结果具有预期值。

Both are valid verifications, and if both are relevant, both should be used. 两者都是有效的验证,如果两者都相关,则都应使用。

For example, consider the following (admittedly artificial) situation: 例如,考虑以下(公认的人为)情况:

You have an interface that performs some mathematical calculation: 您具有执行一些数学计算的接口:

public interface ValueProducer {
    public int getValue(int val);
}

And a class that doubles any result produced by it: 一个将其产生的任何结果加倍的类:

public class Doubler {
    public static int doubleThatResult (ValueProducer producer, int val) {
        return 2 * producer.getValue(val);
    }
}

Testing it would require to assert two things: 测试它需要声明两件事:

  1. That getValue was properly called 正确地调用了getValue
  2. That the result is doubled 结果翻倍

So, eg: 因此,例如:

public class DoublerTest {

    @Test
    public void testDoubleThatResult() throws Exception {
        int value = 7; // Or any other value
        int returnMock = 13; // Or any other value

        ValueProducer producerMock = mock(ValueProducer.class);
        when(producerMock.getValue(value)).thenReturn(returnMock);

        int actual = Doubler.doubleThatResult(producerMock, value);

        verify(producerMock);
        assertEquals(26, actual);
    }
}

Mureinik's answer is absolutely correct—assertions and verifications are complementary, and work quite well together—but doing both for a single behavior may be redundant. Mureinik的答案是绝对正确的-断言和验证是相辅相成的,并且可以很好地协同工作-但对单个行为执行两项操作可能是多余的。

The goal is usually to express the test in the most flexible and implementation-agnostic way possible. 通常,目标是以最灵活且与实现无关的方式表示测试。 State testing (with assertions) is often the most appropriate choice, in that sense: it doesn't matter which methods were called as long as the resulting state is correct. 从这种意义上讲,状态测试(带有断言)通常是最合适的选择:只要结果状态正确,调用哪种方法都没有关系。 A Mockito verification, while possible, may introduce brittleness (where the code behaves correctly but the test is broken). Mockito验证虽然可能,但可能会带来脆性(代码行为正确,但测试已失败)。 Mockito itself warns of this in verify(T) 's Javadoc and the linked article by Mockito's creator Szczepan Faber . Mockito本身会在verify(T)的JavadocMockito的创建者Szczepan Faber的链接文章中对此进行警告。

This redundancy is certainly not the worst thing: It does test a property of the system, and may be a worthwhile endeavor in testing interactions with sensitive, legacy, third-party, or frequently-changing dependencies. 这种冗余肯定不是最坏的事情:它确实测试了系统的属性,并且可能是在测试与敏感的,遗留的,第三方的或频繁变化的依赖关系的交互中值得进行的工作。 If the interaction is unimportant, though, these extra verifications may come at the expense of brittleness. 但是,如果交互作用不重要,则这些额外的验证可能会牺牲脆性。

Other times, confirming correct behavior means testing side-effects—for example, ensuring that someSystem.reset() was called, or testing a cache by verifying a provider was NOT called. 在其他时候,确认正确的行为意味着测试副作用,例如,确保调用了someSystem.reset() ,或者通过验证未调用提供程序来测试缓存。 These are perfect examples for verification, because the interaction with the external service is critical testable behavior. 这些是验证的完美示例,因为与外部服务的交互是关键的可测试行为。 In some of these cases, Mockito verifications are the only way to make the correct assertions. 在某些情况下,Mockito验证是做出正确断言的唯一方法。

Many test cases are a combination of the above, so feel free to use assertions and verifications freely together; 许多测试用例是上述情况的组合,因此可以随意自由使用声明和验证。 just remember that state testing is often sufficient and preferable. 请记住,状态测试通常是足够且可取的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM