如何验证模拟对象的状态?

时间:2016-06-16 00:07:35

标签: unit-testing mockito

我有一个在设备上运行的程序Foo,首先在外部模块Bar上调用method1()然后调用method2()。 当两个被调用时,作为响应,Bar在Foo上调用request()。 要模拟Bar,它有一个对Foo的引用和一个方法call_Request(),它调用foo.request()

// in class BarTest
@Test
public void barFlow() {
    InOrder inOrder = inOrder(mockBar);
    inOrder.verify(mockBar).method1(anyInt());
    inOrder.verify(mockBar).method2();
    // what to put as 'thenCallMethod'?
    when(mockBar.method2()).thenCallMethod().call_Request();
}
...
// in class Bar
public void call_Request() {
    foo.request();
}

我不能简单地在方法2中调用call_Request(),因为只有当两个方法按顺序调用时才会发生响应。其他时候,可能会发生不同的反应。

Mockito技巧会做什么'thenCallMethod'?

(我正在使用与Android Studio 2.1捆绑在一起的Mockito ver 1.10.19)

1 个答案:

答案 0 :(得分:0)

您似乎没有明确定义您所测试的设备是什么。似乎有3种可能性:

  1. locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); Foo进行了单独的测试,被测单元是Bar的一个实例,使用了Foo的模拟和{{1}的实例使用模拟Bar
  2. 正在测试的单元是使用Bar的实际实例的Foo实例,但Foo实例使用Bar模拟
  3. 正在测试的单元是Bar的一个实例,使用Foo的实际实例,后者又使用Foo的现有实例
  4. 如果是案例1.您可以针对Bar测试以下内容:

    Foo

    Bar的测试看起来像:

    @Test
    public void testBar1() {
        Foo mockFoo = Mockito.mock(Foo.class);
        Bar bar = //obtain unit under test that uses mockFoo
    
        bar.method1(1/*or whatever int value is appropriate*/);
        bar.method2();
    
        Mockito.verify(mockFoo).request();
    }
    @Test
    public void testBar1() {
        Foo mockFoo = Mockito.mock(Foo.class);
        Bar bar = //obtain unit under test that uses mockFoo
    
        bar.method2();
        bar.method1(1/*or whatever int value is appropriate*/);
    
        Mockito.verify(mockFoo, Mockito.never()).request();
    }
    

    在第2种情况下,您基本上会从案例1重复Foo的测试。但您只需验证在{1}}的模拟上调用了Bar mockBar = Mockito.mock(Bar.class); Foo foo = //obtain unit under test that uses mockBar // invoke method on foo that would trigger calls to mockBar InOrder inOrder = inOrder(mockBar); inOrder.verify(mockBar).method1(anyInt()); inOrder.verify(mockBar).method2(); FooFoo.request()实例上的调用顺序对此测试用例没有任何意义。

    在第3种情况下,您将无法验证任何调用,因为根本没有使用模拟。

    使用类似

    的内容
    Foo

    没有多大意义,因为你给了一个模拟实现,它可能没有生产代码。