我是Mockito的新手,我想为一些遗留代码编写一个单元测试。在测试我的特定场景时,我确实尝试了一些提到的使用mockito的技术,但我无法找到我的用例的解决方案。下面是我的场景:
我有一个方法a(对数据进行本地处理)和一个方法B(对数据进行一些远程处理)。方法A反过来调用我的方法B,我想调用方法A,当它反过来调用方法B时,我想从方法B返回一个预定义的值,比如一个文件列表。下面是测试类和实际类的示例代码:
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
}
}
我创建了一个类的模拟,并确保当我调用方法a时,方法a的真正方法调用发生,当我调用方法B时,返回模拟结果。
如果我分别测试方法A和方法B,它可以工作,但是当我调用方法A时,方法A又调用方法B,它不会返回方法B的模拟值。
这不是正确的方式做这个电话还是我错过了什么?
如果我理解正确的话,您想要模拟类中的一个方法,而实际上调用同一类中的另一个方法。
这可以使用间谍来完成:使用间谍,对象中的每个方法都被真正调用,除非它被显式地存根:
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
的构造不同于"通常"的构造。如果我们写下面的代码:
when(spy.methodB("", "")).thenReturn(...);
发生的是真正的methodB
在这里被调用,这是我们不想要的。在第二个结构中:
doReturn(...).when(spy).methodB("", "");
未调用methodB
下面是演示间谍的完整测试类:
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
}
}