[英]Unit Testing Generic Repository “Find” Method - MSTest, Moq, EF6
我對單元測試和Moq相當陌生,但是我嘗試使用Moq和MSTest為通用存儲庫設置單元測試。 我敢肯定,很多事情我可能做錯了,但是我確實可以在測試通用存儲庫中基於表達式的參數時使用幫助。 具體來說,我似乎無法讓模擬的存儲庫返回預期的對象列表,這是代碼:
內容:
public class OrderContext : DbContext, IDisposable
{
public virtual DbSet<Order> Orders { get; set; }
public virtual void Commit()
{
base.SaveChanges();
}
}
儲存庫接口/儲存庫
public interface IRepository<T> where T : class
{
IEnumerable<T> GetManyBySearch(Func<T, bool> where);
}
public class RepositoryBase<T> : IRepository<T> where T : class
{
private OrderContext _db;
private DbSet<T> _dbSet;
public RepositoryBase(OrderContext db)
{
_db = db;
_dbSet = _db.Set<T>();
}
// Get many records by search
public virtual IEnumerable<T> GetManyBySearch(Func<T, bool> where)
{
return _dbSet.Where(where).AsQueryable();
}
}
...在我的單元測試中,理想情況下,我將能夠設置與此測試類似的測試,只是我想讓我的存儲庫根據傳遞給GetManyBySearch的表達式返回內存對象數據的子集() 方法。 當前,我的模擬存儲庫將返回整個數據集,而不管傳遞的是什么表達式 。 這是示例:
單元測試
[TestMethod]
[TestCategory("Repository Tests")]
public void Order_Get_Many_By_Search()
{
Mock<OrderContext> mockDb = new Mock<OrderContext>();
Mock<RepositoryBase<Order>> mockRepo = new Mock<RepositoryBase<Order>>(mockDb.Object);
var data = new List<Order>()
{
new Order { OrderId = 1, OrderNumber = 111, OrderDate = DateTime.Now },
new Order { OrderId = 2, OrderNumber = 222, OrderDate = DateTime.Now },
new Order { OrderId = 3, OrderNumber = 222, OrderDate = DateTime.Now }
}.AsQueryable();
var expectedResults = data.Where(m => m.OrderNumber == 222);
var mockSet = new Mock<DbSet<Order>>();
mockSet.As<IQueryable<Order>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Order>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Order>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Order>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
mockDb.Setup(m => m.Set<Order>()).Returns(mockSet.Object);
mockRepo.Setup(m => m.GetManyBySearch(It.IsAny<Func<Order, bool>>()))
.Returns(mockSet.Object.AsQueryable());
List<Order> results = mockRepo.Object.GetManyBySearch(m => m.OrderNumber == 222).ToList(); // This returns the entire "data" dataset
mockRepo.Verify(m => m.GetManyBySearch(It.IsAny<Func<Order, bool>>()), Times.Once());
Assert.AreEqual(2, results.Count()); // This fails :(
}
任何幫助將不勝感激。 提前致謝。
我懷疑測試在指示的行上失敗,因為您的樣本數據包含3個元素,並且您斷言它包含2:
var data = new List<Order>()
{
new Order { OrderId = 1, OrderNumber = 111, OrderDate = DateTime.Now },
new Order { OrderId = 2, OrderNumber = 222, OrderDate = DateTime.Now },
new Order { OrderId = 3, OrderNumber = 222, OrderDate = DateTime.Now }
}.AsQueryable();
// <snip>...
Assert.AreEqual(2, results.Count());
但是,這里更大的問題是在示例中,您實際上是在模擬要測試的方法:
Mock<RepositoryBase<Order>> mockRepo = new Mock<RepositoryBase<Order>>(mockDb.Object);
// <snip>...
List<Order> results = mockRepo.Object.GetManyBySearch(m => m.OrderNumber == 222).ToList();
因此,您無需測試任何生產代碼。 取而代之的是,您只是在測試模擬對象將執行告訴它們的操作。
用實際實例替換模擬存儲庫,然后將所有其他模擬對象注入其中。 然后,這將是對GetManyBySearch
方法返回您期望的良好測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.