gpt4 book ai didi

c# - 我可以创建一个我可以添加的模拟数据库上下文,然后进行搜索吗?

转载 作者:可可西里 更新时间:2023-11-01 08:33:11 25 4
gpt4 key购买 nike

我有一个简单的文档管理器,它被注入(inject)到我在 asp.net c# MVC 项目中的 Controller 中。该项目是数据库优先的,Document 表由 documentId 索引,这是一个自动递增的整数。

我一直在尝试编写一个测试来测试 CreateNewDocument 的以下实现,它在成功添加文档后查找它并返回新文档 ID。

问题是我找不到模拟 MyEntityFrameWorkEntities 的方法,我可以向其中添加文档,然后使用 linq 搜索该文档。我认为它不起作用,因为模拟的 _context.Document.Add 并没有真正做任何事情。

我的问题是:我能否以不同的方式设置我的模拟,以便我可以保持 DocumentManager 不变并编写一个通过的测试?

public class DocumentManager : IDocumentManager
{
private readonly MyEntityFrameWorkEntities _context;

public DocumentManager(MyEntityFrameWorkEntities context)
{
_context = context;
}

public int CreateNewDocument(int userId)
{
var newDocumentGuid = Guid.NewGuid();
var newDocument = new Document
{
UserId = userId,
DateCreated = DateTime.Now,
DocumentGuid = newDocumentGuid
};
_context.Document.Add(newDocument);
_context.SaveChanges();
// the .First here doesn't return anything when called from tests
return _context.Document.First(d => d.DocumentGuid == newDocumentGuid).DocumentId;
}
}

public partial class MyEntityFrameWorkEntities : DbContext
{
public MyEntityFrameWorkEntities() : base("name=MyEntityFrameWorkEntities")
{
}

public virtual DbSet<Document> Document { get; set; }
/* ...etc... */
}

和测试类:

[TestMethod]
public void TestCreateNewDocument()
{
var mockContext = new Mock<MyEntityFrameWorkEntities>();

var mockDocumentDbSet = GetQueryableMockDocumentDbSet();

mockContext.Setup(m => m.Document).Returns(mockDocumentDbSet.Object);

var documentManager = new DocumentManager(mockContext.Object);

var newDocId = documentManager.CreateNewDocument(123);

// This line doesn't get hit as the .First falls over before here
Assert.AreNotEqual(newDocId, 0);
}

private static Mock<DbSet<Document>> GetQueryableMockDocumentDbSet()
{
var data = new List<Document> { GetDocument(111, 11), GetDocument(222, 22), GetDocument(333, 33) }.AsQueryable();
var mockDocumentDbSet = new Mock<DbSet<Document>>();
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.Provider).Returns(data.Provider);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.Expression).Returns(data.Expression);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
return mockDocumentDbSet;
}

private static Document GetDocument(int documentId, int userId)
{
return new Document
{
DocumentId = documentId,
UserId = userId,
DateCreated = DateTime.Now.AddDays(-1),
DocumentGuid = Guid.NewGuid(),
};
}

最佳答案

您可以使用回调设置模拟 DbSet 的 Add() 方法,该方法会将项目添加到支持列表中:

private static Mock<DbSet<Document>> GetQueryableMockDocumentDbSet()
{
var data = new List<Document> { GetDocument(111, 11), GetDocument(222, 22), GetDocument(333, 33) };

var mockDocumentDbSet = new Mock<DbSet<Document>>();
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.Provider).Returns(data.AsQueryable().Provider);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.Expression).Returns(data.AsQueryable().Expression);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.ElementType).Returns(data.AsQueryable().ElementType);
mockDocumentDbSet.As<IQueryable<Document>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
mockDocumentDbSet.Setup(m => m.Add(It.IsAny<Document>())).Callback<Document>(data.Add);
return mockDocumentDbSet;

您随后对 First() 的调用应该能够检索该项目。

关于c# - 我可以创建一个我可以添加的模拟数据库上下文,然后进行搜索吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28433387/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com