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. 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. I am using Moq and have tried the following:

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

Any help greatly appreciated.

有帮助吗?

解决方案 2

I found the answer at this link 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:

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

to

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

Just adding the virtual in. And it all worked.

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.

其他提示

Create an interface for your BlogWebsiteModelContainer, then mock the interface. Also instead of defining Blogs on the interface as DbSet<Blog> define it as IQuerayable<Blog>

You can then create a List and use the .AsQueryable extension:

var contextMock = new Mock<IBlogWebsetModelContainer>();
var mockBlogSet = new List<Blog>();
contextMock.Setup(m => m.Blogs).Returns(mockBlogSet.AsQueryable());
blogRepo = new BlogRepository(contextMock.Object);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top