如何使用内容更改的集合验证方法调用?

时间:2014-06-06 04:34:49

标签: java mockito

使用Mockito我正在尝试验证是否已从其他对象添加和删除某些对象。但是,执行此操作的函数存储集合的实例,更新此集合的内容,并将其传递给我的对象。

当我尝试验证使用正确的对象调用addAll和removeAll时,似乎Mockito实际上持有对集合的引用,因此在调用方法时不知道集合包含什么。一个简化的例子:

class MySUT
{
    private final Collection<Object> objects = new ArrayList<>();
    public MySUT(Object firstObject)
    {
        objects.add(firstObject);
    }

    public void addNewObject(Collection<Object> other, Object newObject)
    {
        other.removeAll(objects);
        objects.clear();

        objects.add(newObject);
        other.addAll(objects);
    }
}

@Test
public void test()
{
    Object firstObject = mock(Object.class);
    Object newObject = mock(Object.class);
    Collection<Object> myObject = mock(Collection.class);

    MySUT sut = new MySUT(firstObject);

    sut.addNewObject(myObject, newObject);

    verify(myObject).removeAll(eq(Collections.singletonList(firstObject)));
    verify(myObject).addAll(eq(Collections.singletonList(newObject)));
}

此测试未能声明使用包含removeAll的列表调用newObject方法,但显然不是。

我无法使用ArgumentCaptor,因为它的工作方式相同 - 所以如何验证已将正确的内容传递给myObject(显然在实际代码中myObject不是一个简单的集合)?

1 个答案:

答案 0 :(得分:1)

好的,我已经解决了,并且认为我会分享以防其他人有同样的问题。我已经让存根返回了一个答案,并在答案实现中将这些句子添加到一个新列表中。然后我断言反对。这有点讨厌,但它确实有效。

class MySUT
{
    private final Collection<Object> objects = new ArrayList<>();
    public MySUT(Object firstObject)
    {
        objects.add(firstObject);
    }

    public void addNewObject(Collection<Object> other, Object newObject)
    {
        other.removeAll(objects);
        objects.clear();

        objects.add(newObject);
        other.addAll(objects);
    }
}

@Test
public void test()
{
    Object firstObject = mock(Object.class);
    Object newObject = mock(Object.class);
    Collection<Object> myObject = mock(Collection.class);

    MySUT sut = new MySUT(firstObject);

    final List<Object> removeAllResult = new ArrayList<>();
    when(myObject.removeAll(anyCollectionOf(Object.class))).thenAnswer(new Answer<Object>()
    {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable
        {
            removeAllResult.addAll((Collection<Object>) invocation.getArguments()[0]);
            return null;
        }
    });

    sut.addNewObject(myObject, newObject);

    verify(myObject).removeAll(anyCollectionOf(Object.class));
    verify(myObject).addAll(anyCollectionOf(Object.class));

    assertThat(removeAllResult.get(0), equalTo(firstObject));
}

如果其他人有更好的/替代解决方案,我仍然想知道:)