考虑下面给出的代码:
@Override
public void A() {
objectA = objectB.B();
objectA.C(someValue);
objectC = new constructor(objectA,callback());
//Rest of the code
}
}
public Callback callback() {
return new callback() {
@Override
public void someMethod(someArgument) {
//some Code
}
};
}
我正在尝试编写一个单元测试用例:
objectB.B()
这就是我使用Mockito和Powermockito所做的:
@InjectMocks
ClassBeingTested testObject;
@Mock
ClassB objectB;
@Mock
ClassC objectC;
@Before()
public void setup() {
when(objectB.B()).thenReturn(new ObjectA("someValue"));
whenNew(objectC.class).withArguments(any(),any()).thenReturn(objectC);
}
@Test()
public void testMethod() {
testObject.A();
}
第一个模拟成功运行,但使用whenNew
的第二个模拟失败,出现以下错误:
org.powermock.reflect.exceptions.ConstructorNotFoundException:在类'ClassC'中找不到带参数类型的构造函数:[null]
如果我使用withArguments(objectA, callback())
我在测试类中执行回调,则会调用实际的构造函数。
我想模拟构造函数调用并限制对实际构造函数的调用。我怎样才能做到这一点?
我无法编辑代码设计,因为这超出了我的范围。
答案 0 :(得分:0)
简而言之,由于使用了2个通用 any()
匹配器,您会收到错误。
当您使用.withArguments(...)
并将其设置为 any()
时,它意味着
.withArguments(null, null)
(因为any()可以匹配几乎任何东西,包括空值),最终折叠为单个null和反射api(PowerMock严重依赖)无法为ClassC(null)发现合适的构造函数。
您可以查看完成工作的org.powermock.api.mockito.internal.expectation.AbstractConstructorExpectationSetup<T>
source的来源
要解决此问题,请考虑使用.withAnyArguments()
,如果您不关心param类型并且存根所有可用的构造函数 OR 在使用 {{1}时指定更具体的类型} 喜欢这样
any()