如何使用内容更改的集合验证方法调用? [英] How to verify method calls with collections where content changes?

查看:73
本文介绍了如何使用内容更改的集合验证方法调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Mockito 我试图验证某些对象是否已从另一个对象中添加和删除.但是完成这项工作的函数会存储一个集合的实例,更新这个集合的内容,并将其传递给我的对象.

Using Mockito I'm trying to verify that certain objects are added and removed from another object. But the function that does this work stores a instance of a collection, updates the contents of this collection, and passes it to my object.

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

When I then try to verify that addAll and removeAll has been called with the correct objects, it seems Mockito is actually holding onto a reference to the collection, therefore has no idea what the collection contained when the methods were called. A simplified example :

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 的列表调用的,而这显然不是.

This test fails claiming that the removeAll method was called with a list containing newObject which clearly it wasn't.

我也不能使用 ArgumentCaptor,因为它的工作方式相同 - 那么我如何验证正确的东西已传递给 myObject(显然在真实代码中)myObject 不是一个简单的集合)?

I can't use ArgumentCaptor either as it works the same way - so how can I verify the correct things have been passed to myObject (obviously in the real code myObject is not a simple collection)?

推荐答案

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

OK, I've worked it out, and thought I'd share in case anyone else has the same problem. I've made the stub return an answer, and in the answer implementation added the arugments into a new list. Then I assert against that. It's a bit nasty, but it works.

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

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

If anyone else has a better/alternative solution, I'd still like to know :)

这篇关于如何使用内容更改的集合验证方法调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆