使用 Mockito 或 PowerMocktio 在 SUT 的方法中模拟本地对象
Mocking a local object inside a method of SUT using Mockito or PowerMocktio
我有如下 class 方法创建本地对象并调用该本地对象的方法。
public class MyClass {
public someReturn myMethod(){
MyOtherClass otherClassObject = new MyOtherClass();
boolean retBool = otherClassObject.otherClassMethod();
if(retBool){
// do something
}
}
}
public class MyClassTest {
@Test
public testMyMethod(){
MyClass myClassObj = new MyClass();
myClassObj.myMethod();
// please get me here..
}
}
当我测试 myMethod
时,我想模拟 otherClassObject.otherClassMethod
到 return 我选择的东西。 otherClassMethod 对消息队列做了一些 class,我不希望在单元测试中这样做。所以当我执行 otherClassObj.otherClassMethod() 时,我想 return 为真。我知道在这种情况下我必须使用工厂来进行 MyOtherClass
实例化,但它是遗留代码,我现在不想更改任何代码。我看到 Mockito 在这种情况下不提供这种设施来模拟 MyOtherClass
但可以使用 PowerMockito。但是,我找不到上述场景的示例,但只找到了静态 class。我应该如何在 SUT 的方法中模拟本地对象?
我还提到了其他一些 OS 问题,例如 - Mocking methods of local scope objects with Mockito 但它们没有帮助。
代码示例会有很大帮助。
好的,这不是真正的答案,但使用 PowerMockito 你可以这样做:
final MyOtherClass myOtherClass = mock(MyOtherClass.class);
// mock the results of myOtherClass.otherClassMethod();
PowerMockito.whenNew(MyOtherClass.class).withNoArguments()
.thenReturn(myOtherClass);
// continue with your mock here
现在,不确定你是否真的需要这里 otherClassMethod 的结果,但如果你不需要,我建议你改为模拟 myMethod()
的结果——除非 myMethod()
是你想要测试的,因为其他方法对其有影响,是的,在这种情况下应该考虑重构......而不是延迟 ad vitam aeternam......
如果您使用的是 PowerMockito,则可以使用 whenNew
方法
它应该看起来像这样:
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class) //tells powerMock we will modify MyClass to intercept calls to new somewhere inside it
public class MyClassTest{
@Test
public void test(){
MyOtherClass myMock = createMock(MyOtherClass.class);
//this will intercept calls to "new MyOtherClass()" in MyClass
whenNew( MyOtherClass.class).withNoArguments().thenReturn( myMock) );
... rest of test goes here
}
另外这个 SO post 也有示例代码 PowerMockito Mocking whenNew Not taking affect
我有如下 class 方法创建本地对象并调用该本地对象的方法。
public class MyClass {
public someReturn myMethod(){
MyOtherClass otherClassObject = new MyOtherClass();
boolean retBool = otherClassObject.otherClassMethod();
if(retBool){
// do something
}
}
}
public class MyClassTest {
@Test
public testMyMethod(){
MyClass myClassObj = new MyClass();
myClassObj.myMethod();
// please get me here..
}
}
当我测试 myMethod
时,我想模拟 otherClassObject.otherClassMethod
到 return 我选择的东西。 otherClassMethod 对消息队列做了一些 class,我不希望在单元测试中这样做。所以当我执行 otherClassObj.otherClassMethod() 时,我想 return 为真。我知道在这种情况下我必须使用工厂来进行 MyOtherClass
实例化,但它是遗留代码,我现在不想更改任何代码。我看到 Mockito 在这种情况下不提供这种设施来模拟 MyOtherClass
但可以使用 PowerMockito。但是,我找不到上述场景的示例,但只找到了静态 class。我应该如何在 SUT 的方法中模拟本地对象?
我还提到了其他一些 OS 问题,例如 - Mocking methods of local scope objects with Mockito 但它们没有帮助。
代码示例会有很大帮助。
好的,这不是真正的答案,但使用 PowerMockito 你可以这样做:
final MyOtherClass myOtherClass = mock(MyOtherClass.class);
// mock the results of myOtherClass.otherClassMethod();
PowerMockito.whenNew(MyOtherClass.class).withNoArguments()
.thenReturn(myOtherClass);
// continue with your mock here
现在,不确定你是否真的需要这里 otherClassMethod 的结果,但如果你不需要,我建议你改为模拟 myMethod()
的结果——除非 myMethod()
是你想要测试的,因为其他方法对其有影响,是的,在这种情况下应该考虑重构......而不是延迟 ad vitam aeternam......
如果您使用的是 PowerMockito,则可以使用 whenNew
方法
它应该看起来像这样:
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class) //tells powerMock we will modify MyClass to intercept calls to new somewhere inside it
public class MyClassTest{
@Test
public void test(){
MyOtherClass myMock = createMock(MyOtherClass.class);
//this will intercept calls to "new MyOtherClass()" in MyClass
whenNew( MyOtherClass.class).withNoArguments().thenReturn( myMock) );
... rest of test goes here
}
另外这个 SO post 也有示例代码 PowerMockito Mocking whenNew Not taking affect