我试图用Moq
来为实体框架代码优先类做一些测试。我对Moq和嘲笑技术很陌生,我想知道是否可以轻松地做一个我将在下面描述的测试。我通过网络搜索了一些解决方案,但大多数都基于存储库模式,我想避免这种情况。如何使用Moq与实体框架IDbSet Count()等方法
我有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; }
}
控制器和动作使用Moq的
测试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);
}
}
最后一个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来测试这个简单的动作,而不是使用完整的存储库模式,据我所知,无论如何这个.Count()
部分硬编码成某种方法是可测试的......也许我只是以一种错误的方式使用模拟?因为我有这样的印象,即使用EF Code First,这应该是相当简单和可行的。
注意:这不适用于异步查询。有关该解决方案的信息,请参阅官方的EF文档:http://msdn.microsoft.com/en-us/data/dn314429.aspx#async – 2014-12-04 03:05:09