使用PowerMockito模拟构造函数不起作用

时间:2017-11-21 20:31:44

标签: java mockito powermock powermockito

我想测试一个使用它的参数化构造函数创建另一个类的对象的方法。即使我嘲笑了MyClass的构造函数,它也会使第三方库在构造函数实现中并导致错误。我使用的是Mockito / PowerMockito。

public class MyClass{

   private MyObj obj;

   MyClass (String profile)
   {
      //some 3rd party library call
      obj = thridPartyLib.someMethod(profile);       
   }

   public String someMethod(){
     return obj.someExternalCall();
   }

}

我想测试的课程

public class ClassTobeTested{

   public void execute(){
       //some code
       // ......
       MyClass myClass = new MyClass(profile);
       myclass.someMethod();
   }
}

到目前为止我尝试了什么 - classUnderTest.execute()最终调用thridPartyLib.someMethod(profile);,它是MyClass构造函数的一部分。

 @RunWith(PowerMockRunner.class)
 @PrepareForTest(MyClass.class)
 public class ClassTobeTestedTest {

     private MyClass mockMyClass;
     private ClassTobeTested classUnderTest;


    @Before
    public void init() {    
       classUnderTest = new ClassTobeTested();
       mockMyClass = PowerMockito.mock(MyClass.class);  
    }

   @Test
   public void testExecute(){

      PowerMockito.whenNew(MyClass.class)
                 .withArguments(Mockito.any())
                 .thenReturn(mockMyClass);

      classUnderTest.execute();     
  }
}

2 个答案:

答案 0 :(得分:2)

只有在使用classUnderTest的间谍或模拟时,您的代码才有效。试试这个。这应该工作

@RunWith(PowerMockRunner.class)
@PrepareForTest( {MyClass.class, ClassTobeTested.class })
public class ClassTobeTestedTest {

  private MyClass mockMyClass;
  private ClassTobeTested classUnderTest;


  @Before
  public void init() {
    classUnderTest = spy(new ClassTobeTested());
    mockMyClass = PowerMockito.mock(MyClass.class);
  }

  @Test
  public void testExecute() throws Exception {

    PowerMockito.whenNew(MyClass.class)
        .withArguments(Mockito.any())
        .thenReturn(mockMyClass);

    classUnderTest.execute();
  }
}

答案 1 :(得分:0)

疼痛可能暗示另一种方法。考虑将工厂注入ClassTobeTested,知道如何创建MyObj的实例。例如:

class MyObjFactory {
   MyObj create(String profile) {
       return new MyClass(profile);
  }
}

然后

public class ClassTobeTested {
    private final MyObjFactory factory;

    public  ClassTobeTested(MyObjFactory factory) {
        this.factory = factory;
    }

   public void execute(){
       //some code
       // ......
      // MyClass myClass = new MyClass(profile);
      MyClass myClass = factory.create(profile);
      myclass.someMethod();
   }
}

因此单元测试变得更简单,只需要模拟工厂并让它返回一个模拟的MyClass实例。然后,可以很容易地验证myclass.someMethod()是否按预期调用。