【问题标题】:Mockito doNothing doesn't work when a Method called with void method call inside当内部调用 void 方法调用方法时,Mockito doNothing 不起作用
【发布时间】:2018-01-10 22:24:02
【问题描述】:

主类

public class BootSample {

    public int call(int m) {
        System.out.println("Entering into Call Method");
        int n = m*10;
        TestUtil testUtil = new TestUtil();
        testUtil.add(m, n);
        System.out.println("End of Call Method Value n : " + n);
        return n;
    }

}

实用类

public class TestUtil {

    public void add(int a, int b) {
        System.out.println(" Entering into TestUtil Method ");
        int c = a +b;
        System.out.println(" End of TestUtil Method Value : " + c);
    }

}

测试类

@RunWith(MockitoJUnitRunner.class)
public class BootSampleTest {

    @Mock
    TestUtil testUtil; 

    @Before
    public void setup() {

    }

    @Test
    public void utilSuccess() throws Exception {
        BootSample bootSample = new BootSample();
        doNothing().when(testUtil).add(any(Integer.class),any(Integer.class));
        int result = bootSample.call(10); 
        assertEquals(result,100);
    }

}

输出:

Entering into Call Method
 Entering into TestUtil Method 
 End of TestUtil Method Value : 110
End of Call Method Value n : 100

我正在尝试使用 doNothing 模拟 util void 方法调用,但不起作用。有人可以帮我解决问题吗?我在我们的应用程序中遇到了类似的功能。

【问题讨论】:

  • 1.此测试将始终失败。 2. 你需要模拟你的班级

标签: java junit mockito powermock


【解决方案1】:

问题是您的call 方法负责创建TestUtil 对象,并且该对象不能被模拟。尝试像这样添加 TestUtil 作为构造函数参数:

public class BootSample {

    private TestUtil testUtil;

    public BootSample(TestUtil testUtil) {
        this.testUtil = testUtil;
    }

    public int call(int m) {
        System.out.println("Entering into Call Method");
        int n = m*10;
        testUtil.add(m, n);
        System.out.println("End of Call Method Value n : " + n);
        return n;
    }
}

然后您需要模拟 TestUtil 类并将模拟传递给 BootSample 类:

BootSample bootSample = new BootSample(testUtil);

【讨论】:

  • 公共类 BootSample { public BootSample(Object mac) { this.mac = mac; } public int call(int m) { System.out.println("进入调用方法");整数 n = m*10; TestUtil testUtil = new TestUtil(); testUtil.add(m, n); System.out.println("调用方法结束值 n : " + n);返回 n; } } 调用者 BootSample bootSample = new BootSample(macObject); bootSample.call(15);
  • 谢谢@Eric。这可行,但我有另一个主构造函数,它接受一些值,我无法使用 testUtil 创建 BootSample 的新构造函数。有没有其他方法?和上面一样
  • 如果您无法将TestUtil 对象添加到新构造函数或现有构造函数,那么您可以使用setter 设置TestUtil 对象并调用它。不知何故,您将不得不注入模拟,无论是通过构造函数还是设置器。
  • 非常感谢。你能解释一下如何使用 setter 会有很大帮助吗。非常感谢你的帮助。非常感谢。
【解决方案2】:

如果您从 TestUtil 类中看到 System.out.printlns,那么它不会被模拟。看起来您缺少 BootSample 上的 @InjectMocks 来告诉 Mockito 将您的模拟 TestUtil 注入其中。

在此处查看文档中的示例:http://static.javadoc.io/org.mockito/mockito-core/2.13.0/org/mockito/InjectMocks.html

【讨论】:

  • 如果你使用@InjectMocks,当然TestUtil也需要注入到你的生产环境中。
  • @InjectMocks 方法的缺点是您可以声明更多模拟,但“忘记”将它们添加到构造函数参数中。您的测试没有出现编译错误。根据TDD的规则,你不能更改生产代码然后......
  • 感谢 Kevin 的意见,这真的很有帮助。
【解决方案3】:

你可以用Mockito.anyInt()代替Integer.class, 代码示例:

Mockito.doNothing().when(testUtil).add(Mockito.anyInt(),Mockito.anyInt());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多