Mockito:如何在调用时存根 void 方法以运行一些代码

2022-09-02 12:36:00

我想存根一个存储库类来测试另一个具有存储库的类(Holder类)。存储库接口支持CRUD操作,并且有很多方法,但我对Holder类的单元测试只需要调用其中两个。存储库接口:

public interface IRepo {
    public void remove(String... sarr);

    public void add(String... sarr);

    //Lots of other methods I don't need now
}

我想创建一个存储库模拟,它可以存储实例,定义仅用于添加删除的逻辑,并提供一种在调用 add 和 remove 后检查存储在其中的内容的方法。

如果我这样做:

IRepo repoMock = mock(IRepo.class);

然后我有一个哑对象,它对每个方法都不执行任何操作。没关系,现在我只需要定义添加和删除的行为。

我可以只创建一个和存根这两种方法来处理集合。然后,我会实例化一个具有 IRepo 的 Holder,注入部分存根的 mock,并在执行该持有者之后,检查该集合以验证它是否包含它应该包含的内容。Set<String>

我已经设法部分存根了一个void方法,就像使用已弃用的方法一样:removestubVoid

Set<String> mySet = new HashSet<>();
stubVoid(repoMock).toAnswer(new Answer<Void>() {

    @Override
    public Void answer(InvocationOnMock invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        String[] stringsToDelete = (String[]) args[0];
        mySet.removeAll(Arrays.asList(stringsToDelete));
        return null;
    }
}).on().remove(Matchers.<String>anyVararg());

但是被弃用了,它并不比为IRepo创建部分实现好多少。有没有更好的方法?

注意:Java 7只能回答,这应该在Android中运行。


答案 1

您可以使用

  Mockito.doAnswer(new Answer<Void>() {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            //DO SOMETHING
            return null;
        }
    }).when(...).remove(Matchers.<String>anyVararg());

来自 Javadoc:

当您想要使用泛型 Answer 存根 void 方法时,请使用 doAnswer()。

Stubbing voids需要与Mockito.when(Object)不同的方法,因为编译器不喜欢括号内的void方法...

例:

    doAnswer(new Answer() {
    public Object answer(InvocationOnMock invocation) {
        Object[] args = invocation.getArguments();
        Mock mock = invocation.getMock();
        return null;
    }}).when(mock).someMethod();

查看 Javadoc 中的示例,了解 Mockito


答案 2

假设您有

public class IFace {
    public void yourMethod() {            
    }
}

然后嘲笑它需要

    IFace mock = Mockito.mock(IFace.class);
    Mockito.doAnswer(new Answer() {
        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            //PUT YOUR CODE HERE
            return null;
        }
    }).when(mock).yourMethod();