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



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

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

我正在尝试使用MicrosoftFakes隔离测试WCF,这样它就不需要数据库了。我们的目标是使用"内存数据库"来实现这一点。我的困难是"清除"EF的dbcontext,这样我就知道它处于一个可以查询、更改和监控的已知状态。

我读过很多关于这可能是个坏主意,因为Linq-to-object和Linq-to-sql之间的Linq提供程序不同。该功能可能在编译时通过,但在运行时失败。为了解决这个问题,我们还通过TFS将集成测试(将WCF连接到真实的数据库)部署到我们的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。这个代码可以从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());

如有任何问题,请随时向咨询

干杯

Kyle

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

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

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

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

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

最新更新