对于在测试方法内部构造的局部对象上模拟局部变量/方法调用,我们目前使用的是PowerMockito库。
我们正在尝试评估是否可以使用mockito-inline(版本3.7.7)来做同样的事情。简而言之,我们正在尝试使用Mockito拦截对象的构造。mockConstruction,以便我们可以在本地创建的对象上指定模拟行为。
下面是一个描述我们用法的场景。由于这是遗留代码,我们现在无法对其进行更改。将依赖项更改为实例变量或其他重构)
简而言之,MyClass类的execute()方法是在局部构造Util类的对象。因为我们想要单元测试execute()的核心逻辑&因此需要模拟在MyClass的execute()方法中创建的本地Util对象上调用的process()方法。
public class MyClass {
public String execute(){
Util localUtil = new Util();
String data = localUtil.process();
//Core logic of the execute() method that needs to be unit tested...
//Further update data based on logic define in process() method.
data = data + " core logic";
return data;
}
}
public class Util {
public String process(){
String result = "real";
//Use various other objects to arrive at result
return result;
}
}
@Test
public void testLocalVar(){
Util util = new Util();
Assertions.assertEquals("real", util.process());
try (MockedConstruction<Util> mockedConstruction = Mockito.mockConstruction(Util.class);) {
util = new Util();
when(util.process()).thenReturn("mocked method data");
String actualData = util.process();
//This works on local object created here.
Assertions.assertEquals("mocked method data",actualData);
//Object,method under test
MyClass myClass = new MyClass();
actualData = myClass.execute();
//This doesn't not works on local object created inside method under test
Assertions.assertEquals("mocked method data" + " core logic",actualData); //Fails
}
}
在这里,我们可以在test方法中本地创建的对象上定义方法上的模拟行为。但同样的事情是不可能的,在实际方法中创建的本地对象。
我可以看到mockedconstruction .construct()确实创建了类的每个对象但是无法在execute()方法中的localUtil.process()上指定模拟行为。
任何建议. .
在您的示例中,您必须在指示Mockito模拟构造函数时存根该行为。Mockito.mockConstruction()
是重载的,并且不仅允许传递您想要模拟构造函数的类:
@Test
void mockObjectConstruction() {
try (MockedConstruction<Util> mocked = Mockito.mockConstruction(Util.class,
(mock, context) -> {
// further stubbings ...
when(mock.process()).thenReturn("mocked method data");
})) {
MyClass myClass = new MyClass();
actualData = myClass.execute();
}
}
您可以在本文中找到更多可能的存根场景。