java - 我应该在测试方法中模拟本地方法调用吗?

标签 java unit-testing testing mocking stubbing

我关于单元测试概念的问题:

class A {
   public void m1() {
      // code
      m2();
      //code
   }

   public void m2() {
      //some code
   }

}

根据最佳实践,我应该如何测试 m1 方法?单元是类还是单元是方法?

我的观点 - 我应该单独测试 m2,而不应该测试 m1m2 集成。

使用我的观点已经足够困难了 - 我应该使用复杂的框架进行测试并使用非常现代的东西。

根据我对单元测试的感觉,测试应该很简单!如果你的代码很好,你就可以测试它,而不需要复杂的东西。但在 m1() 内部调用 m2() 是正常代码。

请澄清我的误解。

更新:

模拟示例(伪代码):

//prepare
A testClass = mock(A.class);
when(testClass.m2()).doNothing();
when(testClass.m1()).callRealMethod();
//execute:
testClass.m1();
//verify
check testClass state after method m1 invocation.

这就是我测试模拟类的方法。这正常吗?

最佳答案

首先,在进行单元测试时,测试所有公共(public)方法。在您的示例中,m1m2 是公共(public)的,因此您需要对两者进行测试。

您可能想要 stub 或模拟 m2 的原因有多种:

  1. 如果在测试 m1 时遇到任何问题,因为 m1 调用 m2、 stub 或模拟 m2 。您可能会遇到的一些问题:

    • m2 可能会调用外部服务
    • m2 可能只是速度慢
    • 使用满足 m2 的参数调用 m1 可能会很困难(您的 m2 没有参数,但我是一般来说)
  2. 有时,当你测试一个调用另一个方法的方法并同时测试另一个方法时,你会发现这两个方法的测试之间存在重复——调用方法的某些测试实际上是在测试被调用的方法。通过将被调用方法从调用方法中 stub 或模拟出来,测试调用方法足以证明被调用方法被调用,并彻底测试被调用方法,可以解决这个问题。

  3. 如果您采用 TDD,您可能会在编写 m2 之前编写 m1。然后,您可以 stub 或模拟 m2,以便您的 m1 测试能够通过,然后继续测试和编写 m2

但是,如果您没有任何理由 stub 或模拟 m2,那就不要这样做。一个方法以不需要 stub 或模拟的方式调用其他方法是常见且合理的。被调用的方法可能简短,或者调用方法可能只是为了可读性而被分解为一堆辅助方法。如果被调用的方法位于另一个类中(因为它被多个调用方法使用),情况也是如此;如果它通过调用它的方法的测试进行了充分测试,并且测试之间没有重复,则不需要 stub 或模拟。

上面的示例在不运行 m1 的情况下模拟 m2 是一件完全正常的事情,并且它完成了工作,但它很丑陋,因为 Mockito 接管了所有操作一个类的方法。您可以使用 Mockito spy 做得更好,此处讨论:What is the difference between mocking and spying when using Mockito? .

A a = spy(new A());
doNothing().when(spy).m2();
a.m1();
# check state of a

关于java - 我应该在测试方法中模拟本地方法调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23653583/

相关文章:

unit-testing - 单元测试 - 数据库和固定装置

ruby-on-rails - Ruby on Rails 2.3.8 : How do I set up my unit tests such that when there is an error, 我可以打印当前作用域中的所有变量吗?

c# - 如何使用 C# 在 webdriver 2 中使用 xpath 获取 webtable 中的确切行数

java - 如果用户创建成功,StackMob 会显示 Toast

unit-testing - 如何确定单元测试的测试用例?

java - SimpleDateFormat 解析错误的时间

android - Mockk 模拟 Kotlin 的私有(private)属性(property)

node.js - 如何使用 nock 库模拟连接?

java - 创建指定参数类型或其子类型的 Arraylist

java - 如何将Stack保存到SharedPreferences?