在编写Junit测试时,Mockito.mock如何更好地使用new?

时间:2016-10-24 10:19:30

标签: java junit mockito

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

2 个答案:

答案 0 :(得分:2)

你似乎在这里弄错了。

您使用模拟来创建“替换对象”,您以某种方式传递到您正在测试的代码中。像这里:

// production code
someObject.expensiveCall();

Mocking允许您为测试中的代码提供一个对象,其中expensiveCall()只是一个“无操作”;除此之外:您还可以使用它来验证确实是从生产代码中实际生成的。

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

这并不意味着您绝对 在整个地方使用模拟。相反:如果你能写一个简单的测试,如:

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

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

答案 1 :(得分:2)

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());
}