【问题标题】:How do I mock the DB models?如何模拟数据库模型?
【发布时间】:2014-04-08 15:39:58
【问题描述】:

我正在尝试测试存储库,因此需要模拟模型容器。我真正需要的是能够在 BlogRepository 中设置返回到 GetBlogs() 的博客。仓库代码是:

private BlogWebsiteModelContainer context;

public BlogRepository(BlogWebsiteModelContainer context)
{
    this.context = context;
}

public IEnumerable<Blog> GetBlogs()
{
    return context.Blogs;
}

所以我希望能够设置context.Blogs 是什么。我正在使用 Moq 并尝试了以下方法:

var mockBlogSet = new Mock<DbSet<Blog>>();
context.Setup(m => m.Blogs).Returns(mockBlogSet.Object);
blogRepo = new BlogRepository(context.Object);

但我在调试时收到此错误消息:

非虚拟(在 VB 中可覆盖)成员的设置无效:m => m.Blogs

非常感谢任何帮助。

【问题讨论】:

    标签: unit-testing moq asp.net-mvc-5 entity-framework-6


    【解决方案1】:

    为您的 BlogWebsiteModelContainer 创建一个接口,然后模拟该接口。另外,不要在接口上将Blogs 定义为DbSet&lt;Blog&gt;,而是将其定义为IQuerayable&lt;Blog&gt;

    然后您可以创建一个列表并使用.AsQueryable 扩展:

    var contextMock = new Mock<IBlogWebsetModelContainer>();
    var mockBlogSet = new List<Blog>();
    contextMock.Setup(m => m.Blogs).Returns(mockBlogSet.AsQueryable());
    blogRepo = new BlogRepository(contextMock.Object);
    

    【讨论】:

    • 我尝试了您的解决方案,但它并没有真正为我工作。创建界面并不简单,可能是由于我的项目中的一些复杂性。尽管使用 AsQueryable() 点,但您确实让我走上了正确的道路。谢谢。
    【解决方案2】:

    我在此链接http://msdn.microsoft.com/en-us/data/dn314429.aspx 找到了答案。所以我的代码如下:

    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);
    

    然后我必须进入我的 BlogWebsiteModelContainer 类并进行更改:

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

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

    只需添加 virtual 即可。一切正常。

    快速说明:首先创建列表然后将其设为.AsQueryable() 的原因是在我的代码中我将原始博客列表分开,以便我可以在测试中对其进行比较。

    【讨论】:

      猜你喜欢
      • 2019-12-28
      • 2021-05-25
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 2014-09-20
      • 2014-02-02
      相关资源
      最近更新 更多