【问题标题】:How is Mockito.mock better that using new while writing Junit tests? [closed]在编写 Junit 测试时,Mockito.mock 比使用 new 更好吗? [关闭]
【发布时间】:2016-10-24 10:19:30
【问题描述】:

我是第一次编写 Junit 测试,并且是 Mockito 框架的新手。 在 Java 中编写 Junit 测试时,使用 Mockito.mock() 比使用 new 运算符创建实例更好吗?

【问题讨论】:

  • 一般来说并没有更好 - 在某些情况下可能会更好。
  • 您被否决了,因为这是一个广泛且主要基于意见的问题。尝试通过提出更直接或更具体的技术问题来改写。
  • 请不要在得到答案后删除您的问题。 SO 的目的是为所有开发人员提供资源,而不仅仅是您自己。

标签: java junit mockito


【解决方案1】:

Mockito 可用于注入当前测试上下文中可能不存在的依赖项,而不是创建用于测试的“虚拟”对象。这些模拟对象不是真实的,而是模拟类的“空”版本,您可以在其上运行 Mockito 提供的各种行为模拟和结果验证方法。

例如下面的类:

class Thing {
    //Some external Dependency which provides the method 'int doWork()'
    private Dependency dependency;
    private int value;
    public void setDependency(Dependency dependency) {
        this.dependency = dependency;
    }
    public int getValue() {
        return value;
    }
    // Calculates something depending on the provided amount.
    public void calculate(int amount) {
        for(int i = 0; i < amount; i++) {
            value += dependency.doWork();
        }
    }
}

然后你可以在你的测试中做这样的事情:

@Test
public void should_calculate_five_times() {
    // Create mock object
    Dependency dependencyMock = Mockito.mock(Dependency.class);
    // Simulate the behaviour of the mock object
    Mockito.when(dependencyMock.doWork()).thenReturn(2);

    // Create object under test
    Thing thingToTest = new Thing();
    // Inject mock object
    thingToTest.setDependency(dependencyMock);
    // Execute method to test
    thingToTest.calculate(5);

    // Expected: dependency.doWork() should have been called 5 times
    Mockito.verify(dependencyMock, Mockito.times(5)).doWork();
    // Since dependencyMock returns 2, when doWork() is called, value should be 10
    Assert.assertEquals(10, thingToTest.getValue());
}

【讨论】:

    【解决方案2】:

    你好像搞错了。

    您使用 mocking 创建“替换对象”,您以某种方式将其传递到您的测试代码中。喜欢这里:

    // production code
    someObject.expensiveCall();
    

    Mocking 允许你给你的测试代码一个对象,其中expensiveCall() 只是一个“no-op”;最重要的是:您还可以使用它来验证实际上是由您的生产代码生成的。

    因此:您使用“模拟”来创建对象以运行测试;它们的唯一目的是使测试真正成为可能,或者至少使测试更容易。有关详细信息,请参阅here

    这并不意味着您绝对必须在所有地方都使用模拟。相反:如果您能够编写一个简单的测试,例如:

    @Test
    public void testWhatever()  {
      assertThat(new Whatever().computeSomething(), is(some expected result));
    }
    

    这是更好的方法(您的测试处理“被测代码”的输入和输出);换句话说:您可以测试合约,而无需处理生产代码的任何内部。

    【讨论】:

    • 谢谢。这很有帮助。
    • 不客气;随时可以投票/接受 ;-)
    猜你喜欢
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多