Pot*_*ipz 5 java unit-testing mockito
我将以我非常新的背景作为序言,一般没有太多的测试经验,以前从未使用过模拟框架。
我正在为访问许多不同 Web 服务的代码编写单元测试,我对此进行了嘲笑。我的许多测试验证了一个调用的结果,其中除了对 ServiceX 的调用之外,我的所有服务调用都成功。我的第一直觉是为@Before 块中的所有模拟设置happy-path 行为,然后为每个测试修改模拟行为。
@Before
public void init(){
when(serviceA.doSomething()).thenReturn(true);
when(serviceB.doSomething()).thenReturn(true);
when(serviceC.doSomething()).thenReturn(true);
when(serviceD.doSomething()).thenReturn(true);
when(serviceE.doSomething()).thenReturn(true);
}
@Test
public void testDoBusinessSuccess(){
String result = businessLogic.doBusiness();
assertThat(result, is("success"));
}
@Test
public void testDoBusinessFailureWhenServiceAFails(){
when(serviceA.doSomething()).thenReturn(false);
String result = businessLogic.doBusiness();
assertThat(result, is("service A is down!"));
}
@Test
public void testDoBusinessFailureWhenServiceBFails(){
when(serviceB.doSomething()).thenReturn(false);
...
Run Code Online (Sandbox Code Playgroud)
这使得每个测试用例都简洁,并且很容易看到正在测试的内容,因为我只指定了偏离规范的行为。
但是我怀疑这不是 Mockito 希望我设置模拟行为的方式,因为当我尝试验证 ServiceB 中的失败意味着 ServiceC 永远不会被命中时,我意识到我when(serviceC.doSomething())在 @Before 中的调用算作对 serviceC 的调用. 也就是说,我verifyZeroInteractions(serviceC)总是失败,因为我调用了when(serviceC.doSomething()).thenReturn(true),即使测试用例从未接触过 serviceC 。
那么最佳实践是什么?我是否最好在每次测试中为每个模拟明确设置行为,即使我会在所有地方重复几乎相同的 5 行?
when(serviceC.doSomething()) in the @Before counted as invocations on serviceC
Run Code Online (Sandbox Code Playgroud)
我怀疑该when构造是否被视为调用,因为那只是存根。
您能否仔细检查您的代码以查看是否serviceC.doSomething是从您的内部调用的@Test
关于最佳实践,我认为您应该只将所有测试用例常见的存根行为转移到@Before
除了代码的外观之外,我认为您可以尝试重构为Chain of Responsibility模式,这应该有助于您编写测试代码。
| 归档时间: |
|
| 查看次数: |
3941 次 |
| 最近记录: |