Mockito的验证和论证捕获者的工作

时间:2017-07-04 12:37:46

标签: java unit-testing testing mockito

我正在尝试测试以下方法

public void saveToMultipleSources(MyObject myObject)
{
    if (myObject.isOfSomeType()) {
        firstDAO.saveObject(myObject);
        myObject.setContent(null);
    }
    secondDAO.saveObject(myObject);
}

我写的测试是

@Test
public void testSaveFeature()
{
    //initialize all objects
    obj.saveToMultipleSources(myObject); //myObject has a valid content.
    Mockito.verify(firstDAO).saveObject(myObject); 
    myObject.setContent(null);
    Mockito.verify(secondDAO).saveObject(myObject);
}

但是在运行时,我得到了firstDAO的verify语句的预期错误和实际参数不同。期望的是具有有效内容的对象,但调用的实际参数的内容设置为null。我也尝试使用ArgumentCaptor完全相同的东西,但得到了相同的结果。

有人可以解释为什么Mockito会这样做吗?我尝试记录整个对象,并且可以在调用firstDA之前看到有效的内容设置。

另外,我该怎么做呢?

1 个答案:

答案 0 :(得分:1)

//initialize all objects
obj.saveToMultipleSources(myObject); //myObject has a valid content.
Mockito.verify(firstDAO).saveObject(myObject); 

问题是将对象内容设置为null是方法的副作用。因此,Mockito将记录的参数(具有有效内容)与您的方法修改的对象(内容已设置为null)进行比较。

  

在这种情况下,我该如何测试呢? - Abhilash Panigrahi

在测试中将myObject设为Mockito.spy()并阻止执行setContent()

@Test
public void testSaveFeature()
{
    //initialize all objects
    MyObject spyOfMyObject = Mockito.spy(myObject);
    doNothing().when(spyOfMyObject).setContent(null); // special null matcher may be needed...

    obj.saveToMultipleSources(spyOfMyObject); 

    Mockito.verify(firstDAO).saveObject(spyOfMyObject); 
    Mockito.verify(spyOfMyObject).setContent(null);
    Mockito.verify(secondDAO).saveObject(spyOfMyObject);
}

但你很可能想确定myObject.setContent(null); 在econdDAO.saveObject(myObject)之前调用;`...

@Test
public void testSaveFeature()
{
    //initialize all objects
    MyObject spyOfMyObject = Mockito.spy(myObject);
    doNothing().when(spyOfMyObject).setContent(null);

    obj.saveToMultipleSources(spyOfMyObject); 

    Mockito.verify(firstDAO).saveObject(spyOfMyObject); 
    InOrder inOrder = Mockito.inOrder(spyOfMyObject,secondDAO);
    inOrder.verify(spyOfMyObject).setContent(null);
    inOrder..verify(secondDAO).saveObject(spyOfMyObject);
}