我确信这是一个非常常见的问题,但我真的无法解决这个问题,我在模拟私有方法,内部调用另一个方法并返回一个集合。 我正在测试的类有一个公共方法,它调用private方法来获取Collection对象。我使用PowerMock创建一个私有方法的间谍。
public void method1(String s)
{
Collection<Object> list = invokePrivate()
}
private Collection<Object> invokePrivate()
{
Wrapper wrapperObj = Factory.getInstance.getWrapper();
Collection<Object> list = wrapperObj.callWrapperMethod(); // This always calls into real method, instead of mocked version.
return list;
}
测试类 - :
因此,为了测试公共方法“method1”,我使用PowerMockito创建了一个间谍来窥探私有方法并返回一个演示列表。
MainClass obj = new MainClass();
MainClass spy = PowerMockito.spy(obj);
PowerMockito.when(spy, method(MainClass.class, "inokePrivate"))
.thenReturn(list); // demo list which exists as a test class member.
上面调用私有方法,它反过来试图调用wrapperObj.callWrapperMethod(),它驻留在一个不同的工件中并在那里打破,因为它找不到那里的某些实现。 所以我尝试模拟wrapperObj.callWrapperMethod。
WrapperClass wr = new WrapperClass();
WrapperClass spy1 = PowerMockito.spy(wr);
when(spy1.callWrapperMethod()).thenReturn(list) // demo list which exists as a test class member.
以上嘲笑再次调用callWrapperMethod()的实际实现并在那里打破。 如何防止调用实际的包装器方法?
帮助我的答案很少 - :
Mockito:How to mock method called inside another method
Testing Private method using mockito
[更新] - :按照我的建议 - :
PowerMockito.doReturn(list).when(spy1).callWrapperMethod(); // This returns me demo list successfully.
但是现在当我从PowerMockito控件调用私有方法进入invokePrivate方法并再次尝试调用原始callWrapperMethod而不是从间谍版本返回列表。
答案 0 :(得分:2)
我建议不这样做。您的私有方法应不使用静态方法检索单件工厂对象。
静电东西破坏&#34;容易&#34;嘲讽;强迫你使用&#34; power&#34;嘲讽;从而产生的问题多于解决的问题。
更改代码以使用依赖注入。做这样的事情:
class YourClass {
private final Factory factory;
public YourClass() {
this(Factory.getInstance(); }
YourClass(Factory theFactory) {
this.factory = theFactory;
...
这将允许您在单元测试中使用第二个构造函数;为您的班级提供(容易模拟的)工厂对象。从而消除了对PowerMock的全部需求。
长话短说 - 代码很难测试;改变代码;而不是测试。作为副作用,您正在提高代码的质量 - 因为您放弃了对该单例对象的硬依赖。
只是为了完成:我还建议避免&#34;打破&#34;得墨忒耳法则(http://en.wikipedia.org/wiki/Law_of_Demeter):如果你的班级需要包装器;然后它应该持有一个包装器对象;如果它需要那个工厂;那么它应该持有一个工厂对象。但你不应该持有一个对象......从那里检索另一个对象,在第二个对象上运行一些东西。正如你所看到的那样 - 这样做完全导致了你所面临的那种问题。