如何模拟数据库模型?

时间:2014-04-08 15:39:59

标签: unit-testing moq asp.net-mvc-5 entity-framework-6

我正在尝试测试存储库,因此需要模拟模型容器。我真正需要的是能够将博客返回到BlogRepository中的GetBlogs()。存储库代码是:

private BlogWebsiteModelContainer context;

public BlogRepository(BlogWebsiteModelContainer context)
{
    this.context = context;
}

public IEnumerable<Blog> GetBlogs()
{
    return context.Blogs;
}

所以我希望能够设置context.Blogs是什么。我正在使用Moq并尝试过以下方法:

var mockBlogSet = new Mock<DbSet<Blog>>();
context.Setup(m => m.Blogs).Returns(mockBlogSet.Object);
blogRepo = new BlogRepository(context.Object);

但是我在调​​试时收到此错误消息:

非虚拟(VB中可覆盖)成员的设置无效:m =&gt; m.Blogs

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

为BlogWebsiteModelContainer创建一个界面,然后模拟界面。而不是在Blog上定义界面上的DbSet<Blog>,而是将其定义为IQuerayable<Blog>

然后,您可以创建一个列表并使用.AsQueryable扩展名:

var contextMock = new Mock<IBlogWebsetModelContainer>();
var mockBlogSet = new List<Blog>();
contextMock.Setup(m => m.Blogs).Returns(mockBlogSet.AsQueryable());
blogRepo = new BlogRepository(contextMock.Object);

答案 1 :(得分:0)

我在此链接http://msdn.microsoft.com/en-us/data/dn314429.aspx找到了答案。所以我的代码变成了以下内容:

List<Blog> blogs = new List<Blog> 
{ 
    new Blog() { Id = 1 },
    new Blog() { Id = 2 },
    new Blog() { Id = 3 },
};

var data = blogs.AsQueryable();

var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

var mockContext = new Mock<BlogWebsiteModelContainer>();
mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);

blogRepo = new BlogRepository(mockContext.Object);

然后我必须进入我的BlogWebsiteModelContainer类并更改:

public DbSet<Blog> Blogs { get; set; }

public virtual DbSet<Blog> Blogs { get; set; }

只需添加virtual。这一切都有效。

快速说明:首先创建列表然后将其设为.AsQueryable()的原因是在我的代码中我将原始博客列表分开,所以我可以在我的测试中对它进行比较。