其他 class 中带有参数的 doNothing void 方法
doNothing void method with params in other class
我目前有 2 个 类:
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
创建一个 junit 测试用例。
但是,我不想调用bClass
中的meth2
,直接执行aClass
中的busslogic
。
类 aClass
和 bClass
是固定的 - 我不能(也不会)更改 aClass
和 bClass
上的代码。
我尝试了很多事情,比如@injectmock 和 doNothing 使用 mokito 和 power mock,但是当我在 aClass
中调用 meth1
时总是调用 meth2
。
我该怎么做才能解决这个问题?
You can do this with Powermockito。 link 解释了所有细节。以下是您的示例的外观。
@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(或类似工具)。 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
}
}
此时,您可以传递一个mock bClass 并调用单参数重载来测试您的业务逻辑。您还可以将 b.meth2()
移出单参数方法并移入 public 无参数方法,如果它的行为更像设置调用。
您可以使用 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;
....
}
我目前有 2 个 类:
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
创建一个 junit 测试用例。
但是,我不想调用bClass
中的meth2
,直接执行aClass
中的busslogic
。
类 aClass
和 bClass
是固定的 - 我不能(也不会)更改 aClass
和 bClass
上的代码。
我尝试了很多事情,比如@injectmock 和 doNothing 使用 mokito 和 power mock,但是当我在 aClass
中调用 meth1
时总是调用 meth2
。
我该怎么做才能解决这个问题?
You can do this with Powermockito。 link 解释了所有细节。以下是您的示例的外观。
@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(或类似工具)
对于任何未来发现这个问题但没有那个约束的读者,bClass 的快速重构将使它更容易测试。
public class aClass{
public void meth1(){
meth1(new bClass());
}
/** Package private for testing. */
public void meth1(bClass b){
b.meth2();
//buss logic
}
}
此时,您可以传递一个mock bClass 并调用单参数重载来测试您的业务逻辑。您还可以将 b.meth2()
移出单参数方法并移入 public 无参数方法,如果它的行为更像设置调用。
您可以使用 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;
....
}