【问题标题】:Mockito NotaMockExceptionMockito NotaMockException
【发布时间】:2015-06-19 03:37:42
【问题描述】:

我遇到了 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();
  }
} 

我知道活动不是模拟,但我不确定解决这个问题的方法,因为secondMethod() 是同一个类中的一个方法。我需要为secondMethod() 编写规则,因为我已经完成了它的单元测试。 secondMethod() 的定义包含外部依赖。我应该嘲笑secondMethod() 中存在的外部依赖项并为它们编写规则而不是secondMethod() 的规则吗?

我发现了这个帖子: Mockito Spy'ing on the object being unit tested 但是,将 secondMethod() 分成不同的类是没有意义的。我的方法与这个类有关。创建一个不同的测试类对我来说似乎不合适。即使使用 spy() 模拟实际类也不是帖子中已经解释的最正确的方法。

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

【问题讨论】:

  • 您不应模拟被测类的方法。你是对的——你不应该嘲笑课堂本身。相反,模拟旨在替换被测类的所有协作者。因此,如果您的类依赖于您的方法中使用其实例的其他类,那么只需模拟掉那些协作者。
  • 异常很清楚,act 不是模拟所以没有 when() 。一些doc 你应该阅读恕我直言

标签: java unit-testing junit mockito


【解决方案1】:

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

但是请注意,无论您是如何 mocking 或 spying 您的对象,都不能在 doReturn 调用中使用匹配器。返回值必须是具体的对象。

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();
  }
} 

【讨论】:

  • 如何在 firstmethod 中查看 str 的值?
【解决方案2】:

这里有一些提示:

  1. 模拟活动。
  2. 使用 when / then / doReturn 调整 secondMethod 的行为
  3. 在调用 firstMethod 时使用 doCallRealMethod。

希望对你有帮助。

【讨论】:

    【解决方案3】:

    在这个例子中没有理由模拟任何东西。由于没有依赖,而且两个方法都是公开的,所以可以直接测试。

    public class ActivityTest() {
    
        private Activity act = new Activity();
    
        @Test
        public void testSecondMethod(){
            assertEquals("expected-value", act.secondMethod());
        }
    
        @Test
        public void testFirstMethod() {
            act.firstMethod();
            // success if no exception occurs
        }
    } 
    

    由于 firstMethod 对 Act 实例或任何依赖项(因为没有)没有任何可检测的影响,因此您可以简单地调用该方法并在没有引发异常的情况下感到满意。人们也可能认为根本不应该测试这种方法。

    我假设给出的示例是一个类的简化,其中调用 firstMethod 实际上确实有副作用,谁知道...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 2011-08-27
      相关资源
      最近更新 更多