使用 mockito-inline 库对本地创建的对象进行模拟方法调用
Mocking method call on object created locally using mockito-inline library
为了模拟本地 variable/method 调用在被测方法内部构造的本地对象,我们目前正在使用 PowerMockito 库。
我们正在尝试评估是否可以使用 mockito-inline(版本 3.7.7)来做同样的事情。
简而言之,我们正在尝试使用 Mockito.mockConstruction 拦截对象的构造,以便我们可以在本地创建的对象上指定模拟行为。
这里有一个场景描述了我们的用法。由于这是遗留代码,我们现在无法更改它。(例如,更改对实例变量的依赖或一些其他重构)
简而言之,classMyClass的execute()方法是在本地构造Utilclass的对象。由于我们想要对 execute() 的核心逻辑进行单元测试,因此需要模拟在 class 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
}
}
在这里,我们可以在测试方法内部本地创建的对象的方法上定义模拟行为。但是在被测实际方法中创建的本地对象不可能发生同样的事情。
我可以看到 mockedConstruction.constructed() 确实创建了 class 的每个对象
但无法在 execute() 方法中的 localUtil.process() 上指定模拟行为 ..
任何建议..
在您的情况下,您必须在指示 Mockito 模拟构造函数时对行为进行存根。 Mockito.mockConstruction()
已重载,不仅允许传递要模拟构造函数的 class:
@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();
}
}
您可以在此 article 中找到更多可能的存根场景。
为了模拟本地 variable/method 调用在被测方法内部构造的本地对象,我们目前正在使用 PowerMockito 库。
我们正在尝试评估是否可以使用 mockito-inline(版本 3.7.7)来做同样的事情。 简而言之,我们正在尝试使用 Mockito.mockConstruction 拦截对象的构造,以便我们可以在本地创建的对象上指定模拟行为。
这里有一个场景描述了我们的用法。由于这是遗留代码,我们现在无法更改它。(例如,更改对实例变量的依赖或一些其他重构)
简而言之,classMyClass的execute()方法是在本地构造Utilclass的对象。由于我们想要对 execute() 的核心逻辑进行单元测试,因此需要模拟在 class 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
}
}
在这里,我们可以在测试方法内部本地创建的对象的方法上定义模拟行为。但是在被测实际方法中创建的本地对象不可能发生同样的事情。
我可以看到 mockedConstruction.constructed() 确实创建了 class 的每个对象 但无法在 execute() 方法中的 localUtil.process() 上指定模拟行为 ..
任何建议..
在您的情况下,您必须在指示 Mockito 模拟构造函数时对行为进行存根。 Mockito.mockConstruction()
已重载,不仅允许传递要模拟构造函数的 class:
@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();
}
}
您可以在此 article 中找到更多可能的存根场景。