简体   繁体   English

如何模拟数据库模型?

[英]How do I mock the DB models?

I am trying to test a repository and so need to mock the Model Container. 我正在尝试测试存储库,因此需要模拟模型容器。 Really all I need is to be able to set the Blogs returned to GetBlogs() in the BlogRepository. 实际上,我所需要做的就是能够将Blog返回的Blog设置为BlogRepository中的GetBlogs()。 The repository code is: 存储库代码为:

private BlogWebsiteModelContainer context;

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

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

So I want to be able to set what context.Blogs is. 所以我希望能够设置context.Blogs是什么。 I am using Moq and have tried the following: 我正在使用Moq,并尝试了以下方法:

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

But I get this error message when I debug: 但是我调试时收到以下错误消息:

Invalid setup on a non-virtual (overridable in VB) member: m => m.Blogs 在非虚拟(在VB中可重写)成员上的无效设置:m => m.Blogs

Any help greatly appreciated. 任何帮助,不胜感激。

Create an interface for your BlogWebsiteModelContainer, then mock the interface. 为BlogWebsiteModelContainer创建一个接口,然后模拟该接口。 Also instead of defining Blog s on the interface as DbSet<Blog> define it as IQuerayable<Blog> 还而不是定义Blog的界面上S作为DbSet<Blog>把它定义为IQuerayable<Blog>

You can then create a List and use the .AsQueryable extension: 然后,您可以创建一个列表并使用.AsQueryable扩展名:

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

I found the answer at this link http://msdn.microsoft.com/en-us/data/dn314429.aspx . 我在此链接http://msdn.microsoft.com/en-us/data/dn314429.aspx中找到了答案。 And so my code became the following: 因此,我的代码如下:

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);

Then I had to go into my BlogWebsiteModelContainer class and change: 然后,我必须进入我的BlogWebsiteModelContainer类并进行更改:

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

to

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

Just adding the virtual in. And it all worked. 只需添加virtual 。所有这些都有效。

Quick note: reason for creating the list first and then making it .AsQueryable() was so in my code I had the original blog list separate so I could compare it in my tests. 快速说明:首先创建列表然后再创建它的原因。在我的代码中, .AsQueryable()是如此,所以我将原始博客列表分开了,以便可以在测试中进行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM