jon*_*lon 11 c# model-view-controller unit-testing entity-framework mocking
我有一个简单的文档管理器,它在asp.net c#MVC项目中注入我的控制器.该项目是数据库优先的,Document表由documentId一个自动递增的整数索引.
我一直在尝试编写一个测试以测试以下实现的测试CreateNewDocument,在成功添加文档之后查找它并返回新的文档ID.
问题是我无法找到一种方法来模拟MyEntityFrameWorkEntities我可以添加文档然后使用linq搜索该文档.我认为它不起作用,因为嘲笑_context.Document.Add并没有真正做任何事情.
我的问题是这样的:我需要改变我的DocumentManager,这样的代码是可测试(例如通过更换.First用.FirstOrDefault和显示,如果返回null函数返回零),或可我(我应该)设置我的嘲笑不同,所以我能保持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... */
}
Run Code Online (Sandbox Code Playgroud)
和测试类:
[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(),
};
}
Run Code Online (Sandbox Code Playgroud)
Lee*_*e D 29
您可以使用回调设置模拟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;
Run Code Online (Sandbox Code Playgroud)
}
您随后对First()的调用应该能够检索该项目.
| 归档时间: |
|
| 查看次数: |
9440 次 |
| 最近记录: |