使用powermockito模拟参数化构造函数

时间:2017-09-01 13:25:41

标签: unit-testing mockito powermockito

考虑下面给出的代码:

@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())我在测试类中执行回调,则会调用实际的构造函数。

我想模拟构造函数调用并限制对实际构造函数的调用。我怎样才能做到这一点?

  

我无法编辑代码设计,因为这超出了我的范围。

1 个答案:

答案 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()