使用 Mockitos 进行单元测试未按预期工作

Unit testing with Mockitos not working as expected

我是 Mockito 的新手,我想为一些遗留代码编写单元测试。在测试我的特定场景时,我确实尝试了一些提到的使用 mockito 的技术,但我无法找到我的用例的解决方案。这是我的场景:

我有一个方法 A(对数据进行本地处理)和一个方法 B(对数据进行一些远程处理)。方法 A 依次调用我的方法 B。我想调用方法 A,当它依次调用方法 B 时,我想 return 来自方法 B 的预定义值,让我们说一个文件列表。这是来自测试 class 和实际 class:

的示例代码
Myclass mc = Mockito.mock(MyClass.class);
when(mc.methodB(param1,param2)).thenReturn(fileSet); // returns mocked fileSet (set of files)
when(mc.methodA(param1,param2)).thenCallRealMethod();  //calls real method A
mc.methodA(param1,param2); //does not return the mocked value from methodB

class MyClass{
   public Set<File> methodB(param1,param2){
        //some processing
        return fileSet;
   }

   public void methodA(param1,param2){
        //some processing
        Set<FileSet> fileSet = methodB(param1,param2);
       //some more processing on returned files
   }

}

我创建了我的 class 的模拟,并确保当我调用方法 A 时,会发生对方法 A 的真实方法调用,而当我调用方法 B 时,模拟结果是 returned。

如果我分别测试方法 A 和方法 B,它可以工作,但是当我调用方法 A 而后者又调用方法 B 时,它不会 return 我从方法 B 中模拟的值。

这不是进行此调用的正确方法还是我遗漏了什么?

如果我理解正确,您想从 class 模拟一个方法,而实际上从同一个 class.

调用另一个方法

这可以使用 spies 来完成:对于间谍,对象中的每个方法都会被真正调用,除非它被明确地存根:

MyClass myClass = new MyClass();
MyClass spy = spy(myClass); // creates a spy for myClass
doReturn(new HashSet<File>() {{ add(new File("file1")); }}).when(spy).methodB("", ""); // stubbing method B
spy.methodA(param1, param2); // calling the real method A

请注意,间谍应谨慎使用,仅用于处理您无法更改的遗留代码。

请注意,存根 methodB 的结构不同于 "usual" 的结构。如果我们编写如下代码:

when(spy.methodB("", "")).thenReturn(...);

正在发生的事情是真正的 methodB 在这里被调用,这是我们不想要的。在第二个构造中:

doReturn(...).when(spy).methodB("", "");

未调用methodB

这是一个完整的测试 class 演示间谍:

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

public class TestClass {

    @Test
    public void test() {
        MyClass myClass = new MyClass();
        MyClass spy = spy(myClass); // creates a spy for myClass
        doReturn(new HashSet<File>() {{ add(new File("file1")); }}).when(spy).methodB("", ""); // stubbing method B
        spy.methodA("", ""); // calling the real method A
    }

}

class MyClass {

    public Set<File> methodB(String param1, String param2) {
        return new HashSet<File>() {{ add(new File("file2")); }};
    }

    public void methodA(String param1, String param2) {
        Set<File> fileSet = methodB(param1, param2);
        System.out.println(fileSet); // prints [file1] and not [file2], meaning the stubbed method was called and not the real one
    }

}