Mockito不能模拟函数调用存在于目标类的构造函数中

时间:2018-01-05 07:53:54

标签: java unit-testing mockito

我正在尝试使用Mockito和JUnit来测试以下类:

public class A {
   private SomeClass someObject;
   private SomeImpClass someImpObject1;
   private SomeImpClass2 someImpObject2;

   public A(SomeImpClass someImpObject1, SomeImpClass2 someImpObject2){
       someObject = makeNewObject(someImpObject1, someImpObject2);
   }

   public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
       return new SomeObject(someImpObject1,someImpObject2);
   }

  public usingSomeObject(){
      someObject.doSomething();
  }
 }

所以,我使用Mockito和JUnit写了一个单元测试:

@RunWith(MockitoJUnitRunner.class)
public class ATest {
  @Mock
  SomeImpClass1 someImpObject1;

  @Mock
  SomeImpClass2 someImpObject2;

  @Mock
  SomeObject someObject;

  @Spy
  A a;

 @Before
public void setUp() {
    when(A.makeNewObject).thenReturn(someObject);
    this.A = new A(this.someImpObject1, someImpObject2);
    when(someObject.doSomething).thenReturn(something);
}
}

我面临的问题是,尽管我已经将函数makeNewObject存根到SomeClass的Mocked对象,但代码流仍然在函数内部(makeNewObject)并且给出了一个空异常。

我做错了什么? 我浪费了一天的时间。

与Mockito不是很流利。

1 个答案:

答案 0 :(得分:1)

你无法通过间谍活动实现目标。 这是因为你的目标是对构造函数中使用的方法进行存根...但是一旦你创建了一个具体的对象并且窥探了它就无法启动存根...无法完成..

我建议在测试类中创建一个私有类,它扩展你的测试类,覆盖构造函数中调用的方法,然后在测试中使用它:

@RunWith(MockitoJUnitRunner.class)
public class ATest {

  @Mock
  SomeObject someObjectMock;

  A a;

 @Before
 public void setUp() {
    this.a = new MyTest();
 }

 private class MyTest extends ATest{

     @Override
     public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
   return someObjectMock;
 }

}

现在你不需要使用它的间谍和存根,因为overriden方法总是返回你在测试中所期望的。