0

我们试图弄清楚单元测试对于基本情况的意义,如下面的代码所示。为此进行单元测试是否有益?我们不是在尝试测试实体框架。我们只是想确保 lambda 表达式做它应该做的事情......我们的想法是我们将使用 DI 来传递 IQueryable 的东西。在实践中它将是 EF 但用于单元测试并且将是 POCO 对象/集合. 这有意义吗?我们才刚刚开始,想要在超出这个基本代码之前掌握这些概念。

   public class CongressRepository
{
    CongressDb_DevEntities context = new CongressDb_DevEntities();

    CongressRepository(DbContext db)
    {
        context = (CongressDb_DevEntities) db;
    }

    public IQueryable<tMember> GetAllMembers
    {
        get { return context.tMembers; }
    }

    public IQueryable<tMember> GetVotingMembers
    {
        get { return context.tMembers.Where(x => x.age > 18); }
    }
}
4

3 回答 3

5

EF 使用 LINQ to Entities,但在模拟 EF 时,您将切换到 LINQ to Objects。这可能会导致单元测试出现误报,因为 LINQ to Entities 和 LINQ to Objects 之间存在差异。如果没有集成测试,您只会在生产环境中看到这些差异/错误。

于 2013-10-18T21:09:10.127 回答
2

单元测试代码的原因之一是确保准确性......

在您的示例中,有人不能在 18 岁生日或从 19 岁生日之间的任何日子投票。我猜它应该是:

public IQueryable<tMember> GetVotingMembers
{
    get { return context.tMembers.Where(x => x.age >= 18); }
}

涵盖一系列合理的成功和失败值的单元测试有助于确保您的代码符合您的意图:-)


但是我们试图找到一个为什么要问的是单元测试是如何工作的。

这可能是一个真正的痛苦!EF6 刚刚发布,可以更轻松地模拟 DbContext,但现在需要进行大量设置......

重要的是 Linq-to-Etities 和 Linq-to-Objects 之间存在差异,因此您确实需要单元测试和集成测试。

虽然有很多博客和相关问题......使用 FakeDbSet 作为一些 google-fu 的起点。

于 2013-10-18T20:55:57.133 回答
1

对于使用 DbContext 的对象进行单元测试,您必须将其作为接口注入到您的存储库对象中。按着这些次序:

1.创建一个包含所有 DbContext 属性的接口,并从中派生您的 DbContext:

 public interface ICongressDbContext {
    IDbSet<Member> Members { get; set; }
    // repeat for all dbsets
 }

2.在构造函数中将此接口提供给您的存储库。这是你的依赖注入:

 private ICongressDbContext context;
 public CongressRepository(ICongressDbContext context){
     this.context = context;
 }

您将希望使用 Autofac 之类的依赖注入框架传递上下文的实例,或者您可以创建一个实例来实例化您的对象。

3.创建IDbSet的通用实现:https ://gist.github.com/LukeWinikates/1309447 。我们称之为 FakeDbContext。

4. 现在您有了一个可模拟的接口和一个通用的 DbSet 实现,您可以创建模拟 DbContext 和模拟 IDbSet。使用起订量,这看起来像:

        var dataContext = new Mock<ICongressDbContext>();
        var members = new List<Member> { // create your test data here };
        // set up the mocked context to use your fake db set with test data
        dataContext.SetupProperty(c => c.Members, new FakeDbContext<Member>(members));

        var repository = new CongressRepository(dataContext.Object);

        // start writing your test methods here

这将测试使用 DbContext 的对象,而不是 DbContext 本身。
除了单元测试之外,您还需要编写使用真实 DbContext 的集成测试。IQueryable 支持的许多方法在访问数据库时不受支持。您还想确保您的数据模型正确映射到数据库。

我希望这可以帮助您入门。

于 2013-10-18T21:57:15.543 回答