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

Posted

技术标签:

【中文标题】FakeItEasy DbSet / IQueryable<T> - 实体框架 6【英文标题】:FakeItEasy DbSet / IQueryable<T> - Entity Framework 6 【发布时间】:2014-04-22 15:31:35 【问题描述】:

我想知道是否有人对 FakeItEasy 的 post 有类似的示例(原始帖子是 here。我一直在尝试找到正确的设置,但无法正确设置。我找不到任何示例在线。我开始自学单元测试,我决定使用 FakeItEasy。到目前为止,我所有的项目都使用实体框架并且不使用 Repository/UOW 模式,因为我认为 DbSet 和 DbContext 对于我的小型应用程序来说已经足够好了。我了解 EF 和单元测试的优缺点,但我仍然想弄清楚这一点。我很确定我的尝试已经完成(见下文),因为我得到的错误是

System.NotImplementedException:成员“IQueryable.Provider”有 未在类型“DbSet1Proxy' which inherits from 'DbSet1”上实现。 '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】:

我对 EntityFramework 一点也不熟悉,也不能确定发生了什么,因为 NotImplementedException 没有堆栈跟踪,但这是我的猜测:

您会看到定义service 的行或调用GetAllRequests 的行引发的异常,而不是A.Fake&lt;DbSet&lt;Request&gt;&gt;() 行。

在我看来,这就像 RequestReadService 的内部结构(那是你的课程,我在别处找不到吗?)或者它所调用的东西依赖于同样实现 IQueryable.Provider 的 DbSet。现在。我不确定为什么它还没有出现。也许是显式的实现把它扔掉了。我可以建议的最好方法(鉴于我完全缺乏 EF6 知识,我还没有尝试过),也许是尝试将接口显式添加到假的:

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

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

或者,在短期内,我不确定还有什么其他解决方法可以建议。也许伪造DbSet 实现的某些接口而不是伪造DbSet 本身?

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

【讨论】:

以上是关于FakeItEasy DbSet / IQueryable<T> - 实体框架 6的主要内容,如果未能解决你的问题,请参考以下文章

使用 FakeItEasy 的私有方法和属性的单元测试用例 [重复]

使用FakeItEasy声明事件已被引发

iQuery stop()

linq join iquery,如何使用defaultifempty

iQuery移动端手势事件插件-jGestures

CF gym102759IQuery On A Tree 17