【问题标题】:Can a Mock framework do this for me?Mock 框架可以为我做到这一点吗?
【发布时间】:2010-02-21 19:25:39
【问题描述】:

我有点迷茫

来自维基: “这意味着真正的模拟......对作为参数传递给方法调用的数据执行测试。”

我从未使用过单元测试或模拟框架。我认为单元测试是用于自动化测试的,那么模拟测试是干什么用的?

我想要的是一个替换我的数据库的对象,我以后可能会使用,但仍然不知道我使用的是什么数据库或 orm 工具。

当我使用模拟程序编写程序时,我是否可以稍后轻松地将它们替换为 POCO 以使实体框架(例如)运行得非常快?

编辑:我不想使用单元测试,但使用 Mocks 作为实体 + 数据库的完全替代品会很好。

【问题讨论】:

标签: database unit-testing mocking poco


【解决方案1】:

是的,我觉得你有点糊涂了。

Mock 框架用于创建“Mock”对象,这些对象基本上伪造了真实对象的部分功能,因此您可以在测试期间将它们传递给方法,而不必费心创建真实对象进行测试。

让我们来看一个简单的例子

假设你有一个“Save()”方法,它接受一个“Doc”对象,并返回一个“布尔”成功标志

public bool Save(Doc docToSave(){...}

现在,如果您想为此方法编写单元测试,您将必须首先创建一个文档对象,并用适当的数据填充它,然后才能测试“Save()”方法。这需要比您真正想做的更多的工作。

相反,可以使用 Mocking 框架为您创建一个模拟“Doc”对象。

框架之间的语法不同,但在伪代码中你会写这样的东西:

CreateMock of type Doc
SetReturnValue for method Doc.data = "some test data"

模拟框架将创建一个 Doc 类型的虚拟模拟对象,该对象在调用 '.data' 属性时正确返回“一些测试数据”。

然后您可以使用这个虚拟对象来测试您的保存方法:

public void MyTest()
{
    ...
    bool isSuccess = someClass.Save(dummyDoc);
    ...
}

模拟框架确保当您的“Save()”方法访问 dummyDoc 对象的属性时,会返回正确的数据,并且可以自然地进行保存。

这是一个稍微做作的例子,在这种简单的情况下,创建一个真正的 Doc 对象可能同样容易,但通常在复杂的位软件中,创建对象可能要困难得多,因为它具有依赖关系在其他事物上,或者它对首先创建其他事物有要求。 Mocking 消除了一些额外的重载,并允许您只测试您正在尝试测试的特定方法,而不必担心 Doc 类的复杂性。

模拟测试只是使用模拟对象而不是真实对象的单元测试。模拟对象并未真正用作实际生产代码的一部分。

如果你想要一些东西来代替你的数据库类以便你以后改变主意,你需要编写接口或抽象类来提供你需要的方法来匹配你的保存/加载语义,那么你可以填写根据您选择的存储类型,推出几个完整的实现。

【讨论】:

  • "如果你想要一些东西来代替你的数据库类以便你以后改变主意,你需要编写接口或抽象类来提供你需要的方法来匹配你的保存/加载语义,然后您可以根据您选择的存储类型填写几个完整的实现。”是的接口......但我需要在某个地方实现它们,所以我必须编写自己的 POCO 作为数据库替换,这些自定义类是否应该模仿实体框架实体类?
  • 你必须有一些数据对象。就我个人而言,我会构建您的业务数据对象以适应您的业务模型,而忘记它们的存储。然后,您可以编写存储层来处理您的业务对象(即使这意味着将它们映射到内部生成的一些 EF 实体类)。 .net 3.5 中的 EF 不支持 POCO,但即将推出的 .net 4.0 版本会支持。
【解决方案2】:

认为您正在寻找的是Repository Pattern。该链接适用于 NHibernate,但一般模式也适用于实体框架。搜索,我找到了Implementing Repository Pattern With Entity Framework

这会抽象出一个接口(或一组接口)背后的实际 O/RM 的细节。

(我不是存储库方面的专家,所以如果有人有,请发布更好的解释/链接。)

然后,在决定 O/RM 之前,您可以在初始开发期间使用模拟(隔离)框架或手工编码假冒/存根。

Unit testing 是您实现全部好处的地方。然后,您可以通过提供模拟或存根存储库来测试依赖于存储库接口的类。您不需要为这些测试设置一个实际的数据库,它们将执行得非常快。测试一次又一次地为自己买单,你的代码质量就会提高。

【讨论】:

  • @TrueWill 我仍然检查了你的链接codeproject.com/KB/database/ImplRepositoryPatternEF.aspx,我不喜欢它,因为它继承自 EntityObject,所以我正在开发一个实现而不是接口;P 我不确定我是哪个 ORM虽然我学习了 EF 12 个月,但我不喜欢它,因为本地 db 有太多的怪癖......
  • @msfanboy - 这可能不是一个好例子;这只是我为该框架找到的一个。我肯定会推荐对接口而不是实现进行编程;这符合存储库模式的精神。你会发现大量关于 SO 上各种 ORM 的优缺点的信息。 :)
猜你喜欢
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多