Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用PowerMockito和Mockito测试对其他工件的调用';s法_Java_Unit Testing_Junit_Mockito_Powermock - Fatal编程技术网

Java 使用PowerMockito和Mockito测试对其他工件的调用';s法

Java 使用PowerMockito和Mockito测试对其他工件的调用';s法,java,unit-testing,junit,mockito,powermock,Java,Unit Testing,Junit,Mockito,Powermock,我确信这是一个很常见的问题,但我真的无法摆脱这个问题,我正在模仿私有方法,它在内部调用另一个方法并返回一个集合。 我正在测试的类有一个公共方法,该方法调用私有方法来获取集合对象。我使用PowerMock创建了一个spy-of-private方法 public void method1(String s) { Collection<Object> list = invokePrivate() } private Collection<Object> invoke

我确信这是一个很常见的问题,但我真的无法摆脱这个问题,我正在模仿私有方法,它在内部调用另一个方法并返回一个集合。 我正在测试的类有一个公共方法,该方法调用私有方法来获取集合对象。我使用PowerMock创建了一个spy-of-private方法

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;
}
上面调用了private方法,该方法反过来尝试调用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()的实际实现,并在其中中断。 如何防止调用包装器方法的实际实现

对我有帮助的答案很少:

[更新]:正如我所建议的那样-:

PowerMockito.doReturn(list).when(spy1).callWrapperMethod(); // This returns me demo list successfully.

但现在,当我从PowerMockito调用私有方法时,控件进入invokePrivate方法,并再次尝试调用原始callWrapperMethod,而不是spy版本的返回列表。

我建议不要这样做。您的私有方法应该而不是使用静态方法检索singleton factory对象

静态的东西打破了“容易”的嘲弄;强迫你使用“权力”嘲弄;因此,制造的问题比解决的问题多

将代码更改为使用依赖项注入。这样做:

class YourClass {
  private final Factory factory;

  public YourClass() {
     this(Factory.getInstance(); }

  YourClass(Factory theFactory) {
     this.factory = theFactory;
  ...
这将允许您在单元测试中使用第二个构造函数;为类提供(易于模拟的)工厂对象。因此,您消除了对PowerMock的全部需求

长话短说——当代码难以测试时;更改代码;而不是测试。作为一个副作用,您正在提高代码的质量——因为您失去了对单例对象的硬依赖


完整地说:我还建议避免“违反”Demeter()定律:如果您的类需要包装器;然后它应该保存一个包装器对象;如果它需要那个工厂;然后它应该保存一个工厂对象。但是你不应该拿着一个东西。。。从那里检索另一个对象,在第二个对象上运行某些东西。如您所见-这样做会导致您面临的问题。

我很感谢您的快速响应;-)使用上面的方法,我仍然需要调用wrapperObj.callWrapperMethod(),在这里我已经模拟了它,因为它位于不同的工件中,我不想调用原始方法。在调用public方法时,它总是调用原始的callWrapperMethod而不是mock对象。是什么阻止模拟工厂返回模拟包装器?
class YourClass {
  private final Factory factory;

  public YourClass() {
     this(Factory.getInstance(); }

  YourClass(Factory theFactory) {
     this.factory = theFactory;
  ...