我关于单元测试概念的问题:
class A {
public void m1() {
// code
m2();
//code
}
public void m2() {
//some code
}
}
根据最佳实践,我应该如何测试 m1
方法?单元是类还是单元是方法?
我的观点 - 我应该单独测试 m2
,而不应该测试 m1
和 m2
集成。
使用我的观点已经足够困难了 - 我应该使用复杂的框架进行测试并使用非常现代的东西。
根据我对单元测试的感觉,测试应该很简单!如果你的代码很好,你就可以测试它,而不需要复杂的东西。但在 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)方法。在您的示例中,m1
和 m2
是公共(public)的,因此您需要对两者进行测试。
您可能想要 stub 或模拟 m2
的原因有多种:
如果在测试
m1
时遇到任何问题,因为m1
调用m2
、 stub 或模拟m2
。您可能会遇到的一些问题:m2
可能会调用外部服务m2
可能只是速度慢- 使用满足
m2
的参数调用m1
可能会很困难(您的m2
没有参数,但我是一般来说)
有时,当你测试一个调用另一个方法的方法并同时测试另一个方法时,你会发现这两个方法的测试之间存在重复——调用方法的某些测试实际上是在测试被调用的方法。通过将被调用方法从调用方法中 stub 或模拟出来,测试调用方法足以证明被调用方法被调用,并彻底测试被调用方法,可以解决这个问题。
如果您采用 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/