将Moq C#代码转换为等效的c#Microsoft Fakes进行单元测试

时间:2014-02-13 10:37:20

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

我正在尝试使用我一直在研究的最近项目进行单元测试。

它涉及SQL Server 2008 R2数据库和使用C#,.NET 4.5和Visual Studio 2013 Premium的WCF服务。我们使用Entity Framework(EF)6.0.1。

我正在尝试使用Microsoft Fakes隔离测试WCF,以便它不需要数据库。我们的目标是使用“内存数据库”。我的困难是“删除”db的dbcontext,所以我知道它处于一个可以被查询,修改和监视的已知状态。

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

我还读到了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。这段代码可以从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());

任何问题随时可以提出

干杯

凯尔

1 个答案:

答案 0 :(得分:2)

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

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

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

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

  4. 我对MS伪造品唯一的问题是它带有VS2012终极版本,因此用户群比MOQ更小。