我目前有两个类:
public class aClass{
public void meth1(){
bClass b = new bClass();
b.meth2();// i dont want to call this method
//buss logic
}
}
public class bClass{
public void meth2(){
// some logic
}
}
目前,我正在为aClass
中的meth1
创建一个单元测试用例。但是,我不想在bClass
中调用meth2
,只执行aClass
中的busslogic
。
类aClass
和bClass
是固定的-我不能(也不会)改变aClass
和bClass
的代码。
我尝试了很多事情,如@injectmock和doNothing使用mokito和power mock,但meth2
总是被调用时,我在aClass
调用meth1
。
我能做些什么来解决这个问题?
您可以使用powermockit完成此操作。这个链接解释了所有的细节。下面是你的例子的样子:
@RunWith(PowerMockRunner.class)
@PrepareForTest(aClass.class)
public class aClassTesting {
@Mock
bClass mockB;
@Test
public void testMeth1(){
//prepare mocks
whenNew(bClass.class).withNoArguments().thenReturn(mockB);
doNothing().when(mockB).meth2();
//run it
aClass instance = new aClass();
aClass.meth1();
//asserts and verify
verifyNew(bClass.class).withNoArguments();
verify(mockB, times(1)).meth2();
}
}
编辑:当你使用@Mock模拟bClass实例时,它会用模拟方法替换该实例中的所有方法。如果您只想模拟bCLass中的一些方法,那么您必须监视bCLass实例,而不是模拟它。Spy只嘲弄您想要的方法。所以只是替换@Mock
与@Spy
在我的例子中,然后只有meth2会被阻止,但不是任何其他方法在bClass。
在不能更改AClass的约束下,唯一的解决方案是使用Powermock(或类似的工具),如Jose Martinez上面提到的。就其本身而言,Mockito不能取代构造函数(它们被视为静态方法调用),因此您唯一的解决方案是重写aClass。
对于没有约束条件的读者来说,快速重构bClass将使这个问题更容易测试。
public class aClass{
public void meth1(){
meth1(new bClass());
}
/** Package private for testing. */
public void meth1(bClass b){
b.meth2();
//buss logic
}
}
此时,您可以传递一个模拟bClass并调用单参数重载来测试您的业务逻辑。如果b.meth2()
的行为更像一个设置调用,您还可以将它从单参数方法移到公共无参数方法中。您可以使用mockito…
public class aClass {
private final bClass b;
public aClass() {
this.b = new bClass()
}
public aClass(bClass b) {
this.b = b;
}
....
}
@RunWith(MockitoJUnitRunner.class)
public class aClassTest {
@Mock
private final bClass b;
@InjectMocks
private aClass a;
....
}