FakeItEasy DbSet / IQueryable <t> - 实体框架6 </t>

时间:2014-03-17 12:23:00

标签: unit-testing dbcontext entity-framework-6 fakeiteasy dbset

我想知道是否有人为FakeItEasy post提供了类似的例子(原帖是here。我一直试图找到正确的设置,但无法做到正确。我可以我没有在网上找到任何例子。我开始自学单元测试,我决定使用FakeItEasy。到目前为止,我所有的项目都使用实体框架而不使用Repository / UOW模式,因为我认为DbSet和DbContext足够我的小规模应用程序。我理解EF和单元测试有优点/缺点,但我仍然想知道这一点。我很确定我的尝试(见下文)因为我得到的错误是

  

System.NotImplementedException:成员'IQueryable.Provider'具有   尚未在类型'DbSet 1Proxy' which inherits from 'DbSet 1'上实现。 'DbSet`1'的测试双精度必须提供   使用的方法和属性。

任何方向都会非常有帮助。谢谢。

var data = new List<Request> 
{ 
request1, 
request2, 
request3
}.AsQueryable();

var fakeDbSet = A.Fake<DbSet<Request>>();

A.CallTo(() => ((IQueryable<Request>)fakeDbSet).Provider).Returns(data.Provider);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).Expression).Returns(data.Expression);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).ElementType).Returns(data.ElementType);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).GetEnumerator()).Returns(data.GetEnumerator());

var fakeContext = A.Fake<RequestPortalContext>();
A.CallTo(() => fakeContext.Requests).Returns(fakeDbSet);

var service = new RequestReadService(fakeContext);
var requests = service.GetAllRequests();

Assert.AreEqual(3, requests.Count);
Assert.AreEqual("Test1", requests[0].Name);
Assert.AreEqual("Test2", requests[1].Name);
Assert.AreEqual("Test3", requests[2].Name);

1 个答案:

答案 0 :(得分:7)

我根本不熟悉EntityFramework,并且无法确定正在进行什么,因为NotImplementedException没有堆栈跟踪,但是这里&#39;我的猜测:

您可以看到从定义service的行或调用GetAllRequests的行而不是A.Fake<DbSet<Request>>()行引发的异常。

听起来像RequestReadService的内脏(是你的班级,我能在其他地方找到它吗?)或者它调用的东西依赖于DbSet也实现IQueryable.Provider。现在。我不确定为什么那不会出现。也许它是明确的实现,抛弃了它。我可以建议的最好的(鉴于我完全缺乏EF6知识,我没试过这个),也许是尝试明确地将这个界面添加到假冒:

A.Fake<DbSet<Request>>(builder => 
                         builder.Implements(typeof (IQueryable<Result>)));

虽然在我输入之后,我读了FakeItEasy issue 31,我担心这可能适用,所以我的想法可能不起作用。再说一次,如果你愿意的话,试试吧。可能不会花很长时间。

或者,在短期内,我不确定提出哪些其他解决方法。也许伪造DbSet实现的一些接口而不是伪造DbSet本身?

更新了:在关于此类事情的另一个问题之后,实际上抓住了EF6以便我可以尝试一下,我创建了Issue 477来跟踪这里似乎存在的潜在问题。