如何將 Moq 與 Entity Framework IDbSet Count() 等方法一起使用
我正在嘗試
Moq對 Entity Framework Code First 類進行一些測試。我對 Moq 和模擬技術非常陌生,我想知道是否可以輕鬆地進行我將在下面描述的測試。我在網上搜尋了一些解決方案,但大多數都是基於儲存庫模式,我想避免這種情況。我有
ITestEntities上下文介面public interface ITestEntities { IDbSet<Order> Orders { get; } IDbSet<Product> Products { get; } IDbSet<User> Users { get; } }然後上下文
public class TestEntities : DbContext, ITestEntities { public TestEntities() : base("name=TestEntities") { } public virtual IDbSet<Order> Orders { get; set; } public virtual IDbSet<Product> Products { get; set; } public virtual IDbSet<User> Users { get; set; } }一個控制器和一個要測試的動作
public class HomeController : Controller { private ITestEntities db; public HomeController() { db = new TestEntities(); } public HomeController(ITestEntities db) { this.db = db; } public ActionResult Index() { var count = db.Users.Count(); ViewBag.count = count; return View(count); } }最後是使用 Moq 的 NUnit 測試
[Test] public void ModelValueShouldBeTwo() { var mockUsers = new Mock<IDbSet<User>>(); mockUsers.Setup(m => m.Count()).Returns(2); var mockDB = new Mock<ITestEntities>(); mockDB.Setup(db => db.Users).Returns((IDbSet<User>)mockUsers); var controller = new HomeController((ITestEntities)mockDB); var view = controller.Index(); Assert.IsInstanceOf<ViewResult>(view); Assert.AreEqual(((ViewResult)view).Model, 2); }問題出在這一行:
mockUsers.Setup(m => m.Count()).Returns(2);. 執行此測試時,我收到以下錯誤:
System.NotSupportedException : Expression references a method that does not belong to the mocked object: m => m.Count<User>()我認為這是由於它
.Count()是一種靜態方法,因此不能被 Moq 模擬。有沒有一種方法可以使用 Moq 而不是使用成熟的儲存庫模式來測試這個簡單的操作,據我所知,無論如何都應該將這.Count()部分硬編碼為某種可測試的方法……也許我只是以錯誤的方式使用模擬?因為我的印像是使用 EF Code First 應該非常簡單且可行。
如果您正在模擬測試實體,則無需進一步模擬
應該這樣做(雖然,我不在 IDE 中,所以可能需要一些調整)
更新以包含新的 InMemoryDbSet
[Test] public void ModelValueShouldBeTwo() { //Build test users var mockUsers = new InMemoryDbSet<User>(){ new User(), new User()}; var mockDB = new Mock<ITestEntities>(); //Set up mock entities to returntest users. mockDB.Setup(db => db.Users).Returns(mockUsers); var controller = new HomeController((ITestEntities)mockDB); var view = controller.Index(); Assert.IsInstanceOf<ViewResult>(view); Assert.AreEqual(((ViewResult)view).Model, 2); }這意味著擴展方法將簡單地使用您提供的測試數據。
請參閱下面有關模擬 dbset http://geekswithblogs.net/Aligned/archive/2012/12/12/mocking-or-faking-dbset.aspx的好文章