我在Mockito junit测试中遇到问题。我是新手,对所面临的问题有些困惑。任何帮助,将不胜感激。

class Activity{

    public void firstMethod(){

      String str = secondMethod();
   }

    public String secondMethod(){
      String str = null;

      /*  some Code */

      return str;
   }
}

获取异常:
*org.mockito.exceptions.misusing.NotAMockException:
 Argument passed to when() is not a mock!*

在下面的代码中
class ActivityTest(){

  Activity act;

  @Before
  public void setup(){
     act = new Activity();
  }

  @Test
  public void testFirstMethod(){

      Mockito.doReturn(Mockito.anyString()).when(act).secondMethod();
      act.firstMethod();
      verify(act).secondMethod();
  }
}

我知道 Activity 不是模拟的,但是我不确定这种方法,因为secondMethod()是同一类中的方法。我已经完成了单元测试,因此需要为secondMethod()编写规则。 secondMethod()的定义包含外部依赖关系。我应该 mock secondMethod()中存在的外部依赖关系并为它们编写规则,而不是secondMethod()规则吗?

我发现了这篇文章:
Mockito Spy'ing on the object being unit tested
但是,将secondMethod()分成不同的类是没有意义的。我的方法与此类有关。在我看来,创建不同的测试类是不合适的。甚至已经使用spy()模拟了实际的类也不是最正确的方法,正如文章中已经解释的那样。

我认为我不应该创建Activity类的模拟,因为这是我正在测试的类。我非常感谢您对此提供的帮助和见解。

最佳答案

如您所述,act不是模拟,因此您不能在其上记录行为。您可以使用 Mockito.spy 监视(或部分模拟)act对象,以便仅记录secondMethod的行为并执行firstMethod的实际代码。

但是请注意,匹配器不能用于doReturn调用中,这取决于您如何对对象进行mockspy编码。返回值必须是一个具体对象。

class ActivityTest() {

  Activity act;

  @Before
  public void setup(){
     act = Mockito.spy(new Activity()); // Here!
  }

  @Test
  public void testFirstMethod(){

      Mockito.doReturn("someString").when(act).secondMethod();
      act.firstMethod();
      verify(act).secondMethod();
  }
}

稍微更优雅的语法允许您使用批注而不是显式调用Mockito.spy,但这确实是一个问题:
@RunWith(MockitoJUnitRunner.class)
class ActivityTest() {

  @Spy
  Activity act = new Activity();

  @Test
  public void testFirstMethod(){

      Mockito.doReturn("someString").when(act).secondMethod();
      act.firstMethod();
      verify(act).secondMethod();
  }
}

09-26 09:40