Java 如何模拟第三方代码的受保护方法

Java 如何模拟第三方代码的受保护方法,java,mocking,mockito,Java,Mocking,Mockito,使用Mockito,我想模拟一个类的属性,以便验证输出 public class MyClass extends ThirdPartyFramework { Output goesHere; @Override protected setup(){ goesHere = new Output(); } //... } public abstract class ThirdPartyFramework { protected setup(){...

使用Mockito,我想模拟一个类的属性,以便验证输出

public class MyClass extends ThirdPartyFramework {
  Output goesHere;

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

  //...      
}

public abstract class ThirdPartyFramework {
  protected setup(){...}
  //...
}
我需要注入输出类的模拟,以便验证我的代码是否编写了正确的输出

  • 但是我不能只调用
    @InjectMock
    ,因为调用了
    setup()
    方法 运行中期并覆盖我的注入

  • 我不能只在
    MyClass
    中公开设置,因为我正在编写测试代码 with是泛型的,需要用于的所有子类
    ThirdPartyFramework
    ,因此我只引用了
    ThirdPartyFramework
    ,这意味着
    setup()
    受到保护


如何为“Goesher”添加一个setter,然后进行setup()检查,仅在Goesher的值为null时更改它。通过这种方式,您可以在测试中注入一个不会被覆盖的值。比如:

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

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

希望这能有所帮助。

你准备好了吗?我这样问是因为Mockito FAQ声明它不支持模拟静态方法,我想在本例中,安装方法需要模拟静态方法来创建模拟,而不是实际输出

我已经将PowerMock用于类似的场景:

whenNew(NewInstanceClass.class).withArguments(any()).thenReturn(mockObject);
也就是说,每次创建NewInstanceClass时,无论使用了什么构造函数参数,也不管是谁在什么时候构造了NewInstanceClass,都会返回我的mockObject

在PowerMock文档中,我还发现了以下示例:

PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)
实际上,即使您绑定到Mockito,您也可以使用它来准确地解决这个问题,它允许您在所有测试中使用Mockito,并使用PowerMock来模拟构建对象。像这样:

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

最后,我通过包装
ThirdPartyFramework
并将该类与
ThirdPartyFramework
类放在同一个包中解决了这个问题


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

这会起作用,但不幸的是,我正在测试框架上工作,所以我不直接控制MyClass,我无法依靠重构MyClass来解决问题。这很好,我可能不得不这样做,为PowerMock添加依赖项是一项工作,但是重写新操作符的能力会使这个问题变得很简单。+1我正要自己提供一个关于这些问题的答案。总是用一些你可以用你需要的方式模仿的东西来包装你的第三方库。