问题
I've been using the Moq objects along with EntityFramework.Testing.Moq extension and I recently hit a bump trying to do a Find. What I had thought was right, that simply doing a setup like this (from the documentation):
// Create some test data
var data = new List<Blog>
{
new Blog{ Id = 1, Name = "BBB" },
new Blog{ Id = 2, Name = "CCC" },
new Blog{ Id = 3, Name = "AAA" }
};
// Create a mock set and context
var set = new Mock<DbSet<Blog>>()
.SetupData(data);
var context = new Mock<BloggingContext>();
context.Setup(c => c.Blogs).Returns(set.Object);
// Create a BlogsController and invoke the Index action
var controller = new BlogsController(context.Object);
var result = await controller.Index();
In the controller, I could do this (again, from the doc):
var query = db.Blogs.OrderBy(b => b.Name);
But, then when I tried to do a DbSet Find, like this using the model's key:
var b = db.Blogs.Find(1);
I would get back null.
Now, I've been able to make this work by doing my setup like this:
context.Setup(m => m.Blogs.Find(It.IsAny<int>()))
.Returns<object[]>(s => data.Find(d => d.Blogs == (int)s[0]));
but I'm left wondering if I was doing something wrong in the first place and if I am over complicating things somehow.
Thanks for any suggestions!
回答1:
If you look at the signature for the SetupData
method
public static Mock<DbSet<TEntity>> SetupData<TEntity>(this Mock<DbSet<TEntity>> mock, ICollection<TEntity> data = null, Func<object[], TEntity> find = null) where TEntity : class
You can see that you have to specify your find predicate in that method call. By doing so, you shouldn't have to do an extra call to setup your context.
You can do so like this:
var set = new Mock<DbSet<Blog>>()
.SetupData(data, objects => data.SingleOrDefault(d => d.Id == (int) objects.First()));
来源:https://stackoverflow.com/questions/32443410/dbset-find-with-moq-entityframework-testing-moq