如何模拟返回的模拟对象的方法
本文关键字:模拟 何模拟 对象 方法 返回 | 更新日期: 2023-09-27 18:31:17
我是最小起订量新手。我正在按照此处提供的指导对实体框架 6 项目进行单元测试。所以我有一个模板化方法来创建假表:
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;
}
使用上述方法可以很好地添加和查询假数据库:
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 还在实体集合上提供"本地"属性,这些属性允许访问未保存的实体。因此,当不嘲笑时,BloggingContext.Blogs.Local 会传回未保存实体的 ObservableCollection 集合。当调用 BloggingContext.SaveChanges() 时,对象将从 BloggingContext.Blogs.Local 移动到 BloggingContext.Blogs。
我想模拟这种行为,所以我创建了一个新类:
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);
}
}
单元测试时,以下代码有效:
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
但是,使用 Local 属性会引发 NPE,因为 Local 属性为 null。
var blog = (from i in context.Blogs.Local select i).FirstOrDefault();//throws NPE
如何成功模拟本地属性?
固定。我在 MockDBSet 模板函数中添加了以下行:
mockSet.Setup(m => m.Local).Returns(data.Local);
并宣布FakeTable的"本地"财产为公共财产。感谢所有感兴趣的人。