【发布时间】:2011-12-27 17:48:37
【问题描述】:
我一直在阅读(并尝试使用)几个 Java 模拟 API,例如 Mockito、EasyMock、JMock 和 PowerMock。我喜欢他们每个人都有不同的原因,但最终还是选择了 Mockito。 请注意,这不是关于使用哪个框架的问题 - 这个问题确实适用于 任何 模拟框架,尽管解决方案将看起来不同,因为 API (显然)不同。
与许多事情一样,您阅读教程、遵循示例并在沙盒项目中修改一些代码示例。但是,当到了实际使用这个东西的时候,你会开始窒息——这就是我的处境。
我真的,真的很喜欢嘲笑的想法。是的,我知道关于嘲笑导致“脆弱”测试与被测类过度耦合的抱怨。但在我自己意识到这一点之前,我真的很想给 mocking 一个机会,看看它是否可以为我的单元测试增加一些好的价值。
我现在正尝试在我的单元测试中积极使用模拟。 Mockito 允许存根和模拟。假设我们有一个 Car 对象,它有一个 getMaxSpeed() 方法。在 Mockito 中,我们可以像这样对它进行存根:
Car mockCar = mock(Car.class);
when(mockCar.getMaxSpeed()).thenReturn(100.0);
这会“存根”Car 对象以始终返回 100.0 作为我们汽车的最大速度。
我的问题是,在编写了一些单元测试之后......我所做的只是给我的合作者打桩!我没有使用任何可用的模拟方法(verify 等)!
我意识到我陷入了一种“stubbing 的心态”,而且我发现它不可能打破。所有这些阅读内容,以及在我的单元测试中使用模拟所带来的所有这些兴奋......我想不出一个用于行为验证的用例。
所以我备份并重新阅读了 Fowler 的 article 和其他 BDD 风格的文献,但我仍然“没有得到”测试双重合作者行为验证的价值。
我知道我错过了一些东西,我只是不确定是什么。有人可以给我一个具体的例子(甚至是一组例子!),比如使用 Car 类,并演示何时行为验证单元测试有利于状态验证测试?
提前感谢您在正确方向上的任何推动!
【问题讨论】:
-
你能给我们看一门你的课吗?例如,上面被存根的 Car 的客户端。那么也许我们可以建议如何使用模拟来测试它。
-
嗨,Tom - 我更喜欢 JB Nizet 的例子,而不是 Car。该示例以及 JB 的解释确实强调了我困惑的根源。我在 JB 回复下方的评论解释了这一点。