【问题标题】:Junit Framework Unit Tests : Mockito.doNothing() doesn't work as expected while mocking void methodsJunit 框架单元测试:Mockito.doNothing() 在模拟 void 方法时无法按预期工作
【发布时间】:2018-02-19 18:24:32
【问题描述】:

我面临一个问题,即“Mockito.doNothing()”似乎没有按预期模拟该方法。 在下面的代码(伪代码)中,“函数 C 的执行”返回异常。 我正在尝试通过模拟 classB 及其方法来测试 FunctionA。 考虑到 functionB 已被模拟为立即返回给调用者(不执行 functionC ),我曾预计 Mockito.verify 会成功。 但是 testFunctionA() 遇到异常(由 functionC 抛出),请记住 functionC 不应该被执行(由于使用 Mockito.doNothing() 模拟了 functionB)。

如果我遗漏了什么,请告诉我吗?任何其他模拟 void 方法(立即返回)的替代方法将不胜感激。

谢谢, 万西。

public class classA {
  public void functionA() {
    int localA;
    String localB;
    B b = new B();
    b.functionB(localA, localB);
   }
 }

public class classB {
  public void functionB(int a, String b) {
    functionC(a, b);
  }
}

public class testClassA {
private classA objectA = new classA();

@Mock
classB objectB;

@Test
public void testFunctionA() {
    Mockito.doNothing().when(objectB).functionB(Mockito.anyInt(),Mockito.anyString());
    objectA.functionA();
    Mockito.verify(objectB, Mockito.times(1)).functionB(Mockito.anyInt(),Mockito.anyString());
   }
}

【问题讨论】:

  • 为什么你认为functionC不会执行?你不是在嘲笑它……

标签: java unit-testing mockito void


【解决方案1】:

您永远不会在classA 的实例中注入classB 模拟,这是被测试的类。因此,当您操作被测对象时,记录的行为将无效:

private classA objectA = new classA();

您可以在ClassA 的构造函数或functionA() 方法中传递ObjectB

例如使用方法来做到这一点:

public void functionA(ClassB classB) {
    int localA;
    String localB;   
    classB.functionB(localA, localB);
}

在你的测试中:

objectA.functionA(objectB);

【讨论】:

    【解决方案2】:

    这里的问题是你永远不会将你的classB 模拟传递给classA 的被测对象。也请参考Mockito Object Creation Mocking Guide

    【讨论】:

      【解决方案3】:

      classA 在每次functionA 调用时创建一个B 的新实例(我想这应该是classB)。因此它永远不会使用 classB 模拟。

      我建议将classB 设为classA 的实例字段

      public class classA {
      
         classB b = new classB();
      
         public void functionA() {
            int localA = 1;
            String localB = "";
      
            b.functionB(localA, localB);
         }
      }
      

      并使用InjectMocks

      public class testClassA {
      
        @InjectMocks
        private classA objectA = new classA();
      
        @Mock
        classB objectB;
      
        @BeforeMethod
        public void init(){
          MockitoAnnotations.initMocks(this);
        }
      
        @Test
        public void testFunctionA() {
          Mockito.doNothing().when(objectB).functionB(Mockito.anyInt(), Mockito.anyString());
          objectA.functionA();
          Mockito.verify(objectB, Mockito.times(1)).functionB(Mockito.anyInt(), Mockito.anyString());
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-21
        • 2020-04-23
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多