Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Moq如何设置EF DbContext扩展方法ToList()以返回mock.Object.ToList()_C#_Entity Framework_Moq_Mstest - Fatal编程技术网

C#Moq如何设置EF DbContext扩展方法ToList()以返回mock.Object.ToList()

C#Moq如何设置EF DbContext扩展方法ToList()以返回mock.Object.ToList(),c#,entity-framework,moq,mstest,C#,Entity Framework,Moq,Mstest,我试图使用Moq模拟实体框架DbContext,特别是它的扩展方法Add()、Tolist()和Find() 我需要Find()和ToList()方法来实际返回存储在我的mockContext.Object中的值 我已经创建了我的数据库集并设置了以下属性: var mockTickets = new Mock<DbSet<Ticket>>(); mockTickets.As<IQueryable<Ticket>>().Setup(m =>

我试图使用Moq模拟实体框架DbContext,特别是它的扩展方法Add()、Tolist()和Find()

我需要Find()和ToList()方法来实际返回存储在我的
mockContext.Object
中的值

我已经创建了我的数据库集并设置了以下属性:

var mockTickets = new Mock<DbSet<Ticket>>();

mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Provider).Returns(tickets.Provider);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Expression).Returns(tickets.Expression);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.ElementType).Returns(tickets.ElementType);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.GetEnumerator()).Returns(() => tickets.GetEnumerator());
这些是我对
Add()
ToList()
方法的断言

//ToList
Assert.AreEqual(result.Count(), mockContext.Object.Tickets.Count());
Assert.IsInstanceOfType(result, typeof(IEnumerable<Ticket>));

//Add
Assert.IsInstanceOfType(result, typeof(Ticket));
mockContext.Verify(x => x.Tickets.Add(It.IsAny<Ticket>()), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Once());
//ToList
Assert.AreEqual(result.Count()、mockContext.Object.Tickets.Count());
IsInstanceOfType(result,typeof(IEnumerable));
//加
Assert.IsInstanceOfType(结果,typeof(票证));
验证(x=>x.Tickets.Add(It.IsAny()),Times.Once());
验证(x=>x.SaveChanges(),Times.Once());
编辑
通过删除
mockContext.Setup(x=>x.Tickets.ToList()).Returns(mockTickets.Object.ToList()),我更进一步了

并加入以下内容:

  • mockContext.Setup(x=>x.Tickets.Add(It.IsAny()).Returns(x=>x)
  • mockContext.Setup(t=>t.Tickets.Find(It.IsAny()).Returns(x=>mockContext.Object.Tickets.Find(x))
最后一行仍然不能产生所需的输出。无法将输入参数的值传递给
Returns()
部分中的
Find()
方法吗


提前感谢您的帮助。

您不能模拟扩展方法,模拟DBContext也不是常见的做法


更好的方法是使用内存中的数据上下文并用测试数据填充它,如下所述:

您可以模拟扩展方法。我同意。或者,如果您不喜欢inmemory方法,典型的替代方法是让您的应用程序逻辑不直接进入DBContext,而是通过存储库(这强制执行更干净的设计)并让这些存储库使用DBContext。然后,通过模拟简单的存储库对应用程序逻辑进行单元测试,并在存储库的实际数据库上编写集成测试。@Thomas我的应用程序确实使用存储库,为了减少代码和更直接地解决问题,我省略了这一点。My
TicketPository
具有在构造函数中初始化的私有DBContext。我实现了一个重载,允许通过构造函数注入DBContext。您是否建议我模拟
ticketpository
而不是模拟DBContext并将其注入
ticketpository
?@X3ntr如果您想测试业务逻辑,那么是的,模拟存储库是一种go@MelGerats我希望测试我的存储库的功能,因此,从技术上讲,这将是DAL而不是BL。REPO是用dbcontext的一个实际实例进行测试的,后面有一个实际的db,没有模拟,也没有集成测试。缺点:将实际数据库作为测试依赖项&这比inmemdb测试慢。好处:您的回购协议是根据生产中使用的相同db技术进行测试的&您可以避免模仿dbcontext。总结:您有一个恼人的设计问题,无法以理想的方式解决。因此,将较小的设计移到一个地方,并保持设计的其余部分干净。
mockContext.Setup(x => x.Tickets.Add(It.IsAny<Ticket>())).Returns(It.IsAny<Ticket>());
mockContext.Setup(x => x.Tickets.ToList()).Returns(mockTickets.Object.ToList());
mockContext.Setup(x => x.Tickets.Find(It.IsAny<int>())).Returns(It.IsAny<Ticket>());
//ToList
Assert.AreEqual(result.Count(), mockContext.Object.Tickets.Count());
Assert.IsInstanceOfType(result, typeof(IEnumerable<Ticket>));

//Add
Assert.IsInstanceOfType(result, typeof(Ticket));
mockContext.Verify(x => x.Tickets.Add(It.IsAny<Ticket>()), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Once());