gpt4 book ai didi

c# - 如何模拟返回的模拟对象的方法?

转载 作者:行者123 更新时间:2023-11-30 17:45:52 24 4
gpt4 key购买 nike

我是最小起订量的新手。我正在按照提供的指导对 Entity Framework 6 项目进行单元测试 here .所以我有一个模板化的方法来创建假表:

    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

如何成功模拟 Local 属性?

最佳答案

已修复。我在 MockDBSet 模板函数中添加了以下行:

        mockSet.Setup(m => m.Local).Returns(data.Local);

并将 FakeTable 的“Local”属性声明为 public。感谢所有感兴趣的人。

关于c# - 如何模拟返回的模拟对象的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27041615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com