2013-01-31 54 views
3

使用的Mockito我想嘲弄一个类的属性,所以我可以验证输出如何嘲笑的第三方代码保护的方法

public class MyClass extends ThirdPartyFramework { 
    Output goesHere; 

    @Override 
    protected setup(){ 
    goesHere = new Output(); 
    } 

    //...  
} 

public abstract class ThirdPartyFramework { 
    protected setup(){...} 
    //... 
} 

我需要注入输出类的模拟这样我就可以验证我的代码编写了正确的输出。

  • 但我不能只@InjectMock因为setup()方法被称为 中期运行并覆盖我注射。

  • 我不能只是让公众建立在MyClass因为测试代码我工作 是通用的,需要为 ThirdPartyFramework所有子类的工作,所以我只有一个参考ThirdPartyFramework,这意味着setup()受到保护。

回答

1

我最终通过缠绕ThirdPartyFramework,并把这个类在同一个包中ThirdPartyFramework类解决这个。

这样我就可以用Mockito来嘲笑受保护的方法。然后,我可以使用@InjectMock来注入对象的模拟,并通过该模拟来控制其方法调用。

+1

+1我正准备自己提供这些答案。总是将你的第三方库包装成你可以以你需要的方式实际模拟的东西。 –

0

如何为“goesHere”添加一个setter,然后进行setup()检查,并且只有当其为null时才更改goesHere的值。这样你可以在测试中注入一个不会被覆盖的值。例如:

protected void setGoesHere(Output output){ 
    goesHere = output; 
} 

@Override 
protected void setup(){ 
    if(goesHere != null) goesHere = new Output(); 
} 

希望这会有所帮助。

+0

这将工作,但不幸的是我正在做一个测试框架的工作,所以我不直接控制MyClass,我不能依靠重构MyClass来解决问题。 –

1

您是否设置了Mockito?我询问自Mockito FAQ Mockito FAQ指出它不支持嘲弄静态方法,我猜你在这种情况下需要使用setup方法来创建你的模拟而不是实际的输出。

我已经使用PowerMock了类似的情况:

whenNew(NewInstanceClass.class).withArguments(any()).thenReturn(mockObject); 

它说,每次NewInstanceClass被创建我mockObject没有返回此事已使用什么构造函数参数和谁在什么时候建造NewInstanceClass。

在PowerMock文档我也发现下面的例子:

PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject) 

其实你可以使用它,即使你被绑定到的Mockito,PowerMock contains helpers for Mockito正好解决了这个问题,让你用对的Mockito所有测试和PowerMock模拟构建对象。就像这样:

whenNew(Output.class).withNoArguments().thenReturn(yourOutputMock); 
+0

这很好,我可能不得不这样做,添加PowerMock的依赖关系是一项工作,但覆盖新运算符的能力会使这个问题变得微不足道。 –