[英]How can I mock a method of a returned mock object?
I am novice to Moq. 我是Moq的新手。 I am unit testing an Entity Framework 6 project, following guidance provided here .
我按照此处提供的指导对实体框架6项目进行单元测试。 So I have a templated method to create the fake tables:
所以我有一个模板化的方法来创建假表:
protected Mock<DbSet<TheType>> MockDBSet<TheType>(List<TheType> data) where TheType : class
{
var mockSet = new Mock<DbSet<TheType>>();
var dataSet = data.AsQueryable();
mockSet.As<IQueryable<TheType>>().Setup(m => m.Provider).Returns(dataSet.Provider);
mockSet.As<IQueryable<TheType>>().Setup(m => m.Expression).Returns(dataSet.Expression);
mockSet.As<IQueryable<TheType>>().Setup(m => m.ElementType).Returns(dataSet.ElementType);
mockSet.As<IQueryable<TheType>>().Setup(m => m.GetEnumerator()).Returns(dataSet.GetEnumerator());
mockSet.Setup(x => x.Add(It.IsAny<TheType>()))
.Returns(new Func<TheType, TheType>(x =>
{
data.Add(x);
return data.Last();
}));
return mockSet;
}
Using the above works fine for adding and querying the fake database: 使用上面的工作正常添加和查询假数据库:
var db = new Mock<BloggingContext>();
db.Setup(m => m.Blog s).Returns(MockDBSet<Blog >(
new List<Blog>()
).Object);
BloggingContext context = db.Object;
Blog blog= new Blog();
context.Blogs.Add(blog); //fine
Assert.IsTrue(context.Blogs.Count() == 1); //fine
EF also provides the "Local" property on the entity collections which give access to un-saved entities. EF还在实体集合上提供“本地”属性,用于访问未保存的实体。 So, when not mocking, BloggingContext.Blogs.Local passes back a ObservableCollection collection of unsaved entities.
因此,在不进行模拟时,BloggingContext.Blogs.Local会传回一个未保存实体的ObservableCollection集合。 Objects are moved from BloggingContext.Blogs.Local to BloggingContext.Blogs when the BloggingContext.SaveChanges() is called.
调用BloggingContext.SaveChanges()时,对象从BloggingContext.Blogs.Local移动到BloggingContext.Blogs。
I wanted to mock this behavior, so I created a new class: 我想模仿这种行为,所以我创建了一个新类:
public class FakeBlogs : List<Blog>
{
ObservableCollection<Blog> _local = new ObservableCollection<Blog>();
ObservableCollection<Blog> Local { get { return _local; } }
public void Add (Blog item)
{
_local.Add(item);
}
}
When unit testing, the following code works: 单元测试时,以下代码有效:
var db = new Mock<BloggingContext>();
db.Setup(m => m.Blog s).Returns(MockDBSet<Blog>(
new FakeBlogs() //<===== Changed to use FakeBlogs
).Object);
BloggingContext context = db.Object;
Blog blog= new Blog();
context.Blogs.Add(blog); //fine
Assert.IsTrue(context.Blogs.Count() == 1); //fine
However, a using the Local property throws a NPE as the Local property is null. 但是,使用Local属性会抛出NPE,因为Local属性为null。
var blog = (from i in context.Blogs.Local select i).FirstOrDefault();//throws NPE
How can I mock the Local property successfully? 如何成功模拟Local属性?
Fixed. 固定。 I added the following line to the MockDBSet template function:
我将以下行添加到MockDBSet模板函数中:
mockSet.Setup(m => m.Local).Returns(data.Local);
And declared the "Local" property of FakeTable as public. 并宣布FakeTable的“Local”属性为public。 Thanks to all who took an interest.
感谢所有感兴趣的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.