【问题标题】:Converting Moq C# code to equivalent c# Microsoft Fakes for unit testing将 Moq C# 代码转换为等效的 c# Microsoft Fakes 以进行单元测试
【发布时间】:2014-02-13 10:37:20
【问题描述】:

我正在尝试对我最近从事的一个项目进行单元测试。

它涉及一个 SQL Server 2008 R2 数据库和一个使用 C#、.NET 4.5 和 Visual Studio 2013 Premium 的 WCF 服务。我们使用实体框架 (EF) 6.0.1。

我正在尝试使用 Microsoft Fakes 单独测试 WCF,以便它不需要数据库。我们的目标是使用“内存数据库”来做到这一点。我的困难是为 EF “存根” dbcontext,所以我知道它处于可以查询、更改和监视的已知状态。

我已经阅读过这可能是个坏主意,因为 linq-to-objects 与 linq-to-sql 之间的 Linq 提供程序不同。该功能可以在编译时通过,但在运行时失败。为了解决这个问题,我们还进行了集成测试(将 WCF 连接到真实数据库),一旦通过 TFS 部署到我们的 DEV 服务器。

我还阅读了有关 dbcontext 可以使用 MS FAKES 填充但感觉不对。

此外,添加存储库模式(依赖注入 (DI))不会导致我们的代码覆盖率增加,这是我们期望的结果之一。

然后我找到了这篇文章http://msdn.microsoft.com/en-gb/data/dn314429.aspx和这篇文章http://frankdecaire.blogspot.co.uk/2013/11/entity-framework-6-mocking-and-unit.html?showComment=1392224065716

这实现了我想做的,但使用了起订量。此代码可以从 Moq 转换为 MS FAKES 吗? FAKES 是否能够完成 Moq 所做的所有事情,还是我也应该学习 Moq 以增加我对 FAKES 的有限知识?

var mockSet = new Mock<DbSet<account>>();
mockSet.As<IQueryable<account>>().Setup(m => m.Provider)
       .Returns(data.Provider);
mockSet.As<IQueryable<account>>().Setup(m => m.Expression)
       .Returns(data.Expression);
mockSet.As<IQueryable<account>>().Setup(m => m.ElementType)
       .Returns(data.ElementType);
mockSet.As<IQueryable<account>>().Setup(m => m.GetEnumerator())
       .Returns(data.GetEnumerator());

有什么问题可以问

干杯

凯尔

【问题讨论】:

  • 如何使用带有 DI 的存储库模式不会增加代码覆盖率?如果您想在没有任何其他依赖项的情况下测试 WCF 服务,则应使用 DI 将单元测试中的这些依赖项替换为模拟或存根。
  • @Wouter de Kort,在查看您的评论后,我正在重构我们的代码以将业务逻辑移出存储库类并返回到主 WCF 服务类。然后,存储库类将仅通过 EF6 执行数据操作。我们的代码覆盖率将以这种方式增加。我是 DI 和存储库的新手,所以我认为这样做是错误的。我读过的另一个博客说很难对糟糕的代码进行单元测试,除了我缺乏知识之外,这肯定是这种情况!我仍然想知道是否有人可以回答我之前所说的问题:-)
  • 听起来不错 :) 我写了一篇关于将代码重构为 DI 以使其更具可测试性的文章:wouterdekort.blogspot.nl/2012/03/… 也许它可以提供帮助!
  • 这听起来像 Fakes 肯定不会有问题,但我不完全明白你的目标是什么。我知道你想伪造一些东西,可能是你展示的代码,但你没有在任何地方声明过。您很可能需要使用垫片。

标签: c# entity-framework unit-testing moq microsoft-fakes


【解决方案1】:

IMO,您需要通过采用更分层的方法来开始解耦您的代码。我不太确定通过单独测试 WCF 需要实现什么。 我建议有三层及其测试如下 -

  1. 数据访问 - 使用 EF 及其 DB 上下文并实现数据访问接口。您应该在不模拟 EF 的数据库上下文的情况下对此进行单元测试。该层的测试将取决于“状态”。我的意思是,您的测试将使用真实数据和数据库进行 CRUD 操作。您只需要确保在测试运行后不会将更改保留到数据库。可以使用 Spring.Net 的测试库来实现这一点,或者只是在事务范围内运行测试并在每次测试运行后回滚事务(在清理中)。

  2. 业务逻辑 - 包含业务逻辑并与数据访问接口一起使用。使用任何 DI 框架,如 spring.net 或 ms unity 来注入数据访问层。您应该通过尝试避免实际的数据库调用来对此进行单元测试。这就是 NMock、Rhinomock 或 MOQ 之类的东西出现的地方。使用模拟设置边界和异常条件,并确保您的业务逻辑解决所有问题。

  3. WCF 服务层 - 与您的操作和数据合同一起工作。理想情况下,仅将调用转发到业务逻辑并将响应转换为数据合约。我更喜欢在这个级别进行两种类型的测试:a)用于测试翻译和正确呼叫转移的单元测试。 b) 使用代理的一些基本集成测试和一些无需任何模拟即可通过整个堆栈的测试数据。

我对 MS fakes 的唯一问题是它附带 VS2012 终极版本,因此用户群比 MOQ 之类的产品少得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    相关资源
    最近更新 更多