我刚刚读了维基百科的文章 模拟对象, ,但我仍然不完全清楚他们的目的。看起来它们是由测试框架创建的对象,而实际对象过于复杂或不可预测(您 100% 确定模拟对象的值是什么,因为您完全控制它们)。

然而,我的印象是所有测试都是用已知值的对象完成的,所以我一定错过了一些东西。例如,在一个课程项目中,我们的任务是开发一个日历应用程序。我们的测试套件由我们确切知道它们是什么的事件对象组成,因此我们可以测试多个事件对象、各种子系统和用户界面之间的交互。我猜这些是模拟对象,但我不知道为什么你不这样做,因为如果没有已知值的对象,你就无法测试系统。

有帮助吗?

解决方案

模拟对象不仅仅是具有已知值的对象。它是一个与无法在测试中使用的复杂对象(如数据库连接和结果集)具有相同接口的对象,但具有您可以在测试中控制的实现。

有一些模拟框架允许您动态创建这些对象,本质上允许您说类似的话:使用 foo 方法创建一个对象,该方法接受 int 并返回 bool。当我传递 0 时,它应该返回 true。然后您可以测试使用 foo() 的代码,以确保它做出适当的反应。

Martin Fowler 有一篇关于嘲笑的精彩文章:

其他提示

想想拥有客户端和服务器软件的经典案例。要测试客户端,您需要服务器;要测试服务器,您需要客户端。这使得单元测试几乎不可能 - 不使用模拟。如果您模拟服务器,则可以单独测试客户端,反之亦然。

模拟的重点不是复制它嘲弄的东西的行为。它更像是一个简单的状态机,其状态变化可以通过测试框架进行分析。因此,客户端模拟可能会生成测试数据,将其发送到服务器,然后分析响应。您希望对特定请求做出某种响应,因此您可以测试是否得到它。

我同意 @Lou Franco 说,你一定要阅读@Lou Franco指出的关于测试双打的优秀Martin Fowler文章。

任何测试double(假,存根或模拟)的主要目的是隔离被测对象,以便您的单元测试仅测试该对象(而不是它的依赖关系以及它与之协作或交互的其他类型)。 / p>

可以使用提供对象所依赖的接口的对象来代替实际的依赖关系,以便可以预期会发生某些交互。这可能很有用,但围绕基于状态和基于交互的测试存在一些争议。过度使用模拟期望将导致脆弱的测试。

测试双精度的另一个原因是删除对数据库或文件系统或其他昂贵的设置或执行耗时操作的依赖性。这意味着您可以将您感兴趣的对象单元测试所需的时间保持在最低限度。

以下是一个示例:如果您正在编写填充数据库的代码,则可能需要检查特定方法是否已将数据添加到数据库中。

设置数据库的副本以进行测试存在的问题是,如果假设在调用测试方法之前没有记录,之后有一条记录,则需要将数据库回滚到先前的状态,从而添加运行测试的开销。

如果您假设只有一个记录比以前多一个,它可能会与连接到同一数据库的第二个测试人员(甚至是同一代码中的第二个测试人员)发生冲突,从而导致依赖性并使测试变得脆弱。

模拟允许您保持测试彼此独立并易于设置。

这只是一个例子 - 我相信其他人可以提供更多。

我同意其他贡献者100%同意这个主题,特别是对Martin Fowler文章的推荐。

您可能对我们的书感兴趣,请参阅 http://www.growing-object -oriented-software.com/ 。它是用Java编写的,但这些想法仍然适用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top