0

看到一些针对模拟测试 EF 的强烈建议,尤其是 Code First,我决定对专用于测试的 SqlCe 数据库进行集成测试,然后在 DbContext 提供的工作单元和存储库的下游使用纯单元测试和数据库集。

我只是不清楚在哪里画线以及在哪里测试什么。我知道当我确信 DAL 特定的集成测试涵盖了它的内部时,我可以在我的服务层中模拟 DAL,但是我在 DAL 中测试什么?似乎没有太多意义的测试来查看我是否可以保存和读取对象,因为 EF 是外部的并且已经过测试。

4

4 回答 4

1

您将使用集成测试在 DAL 中测试您的映射和查询。例子:

public class Service {
   private readonly IDAL _dal;

   public Service(IDAL dal) {
       // Not null validation here
       _dal = dal;
   }

   public void DoSomething() {
       SomeData data = FindSomeData();
       // Do some logic
       _dal.Commit();
   }

   protected virtual SomeData FindSomeData() {
       return _dal.SomeData.Where(...).FirstOrDefault();
   }
}

这是一个非常简化的示例,显示:

  • Service依赖于DALDAL接口通过构造函数注入传递。
  • Service包含您想要测试以了解逻辑是否正确执行的公共 DoSomething 方法。但是这种方法也依赖于数据库查询和数据库持久性(Commit)。
  • 查询是您的逻辑的一部分,但执行此类查询是单独的关注点,因此它由自己的方法处理。在更复杂的情况下,此方法可以在其他类中注入到Service该类(存储库)中。这些查询方法的关键标准是:
    • 他们不回来IQueryable
    • 他们不接受Expression<>作为参数

如何单元测试DoSomething方法:

  • 在这个简单的示例中,您的测试类将从Service类派生并覆盖FindSomeData以返回测试数据。在注入的情况下,您将改为为注入的类定义假。
  • 您还将模拟IDAL,您可以验证是否Commit已调用

您应该使用什么集成测试:

  • FindSomeData您应该为查询真实数据库创建测试
  • 一般来说,您还应该进行集成测试,Commit但实现起来更加困难,因为该示例直接从DoSomething. 您不想再次测试该方法,并且同时Commit方法具有太多通用案例,因为它只是将所有更改从当前上下文刷新到数据库。我通常对插入、更新和删除每个实体类型进行单独的测试。当该DoSomething方法进行一些复杂的修改时,您可以将该方法拆分为两种方法,一种由单元测试处理,用于真实逻辑,另一种由集成测试覆盖,用于您的逻辑可以产生的不同持久性场景。
于 2012-08-30T08:52:52.023 回答
0

我们通常在 DB 方面测试的是复杂对象图是否可以正确插入、更新、删除;基本上测试更复杂的映射。
在我看来,测试是否可以插入具有 3 个原始值属性的对象并没有什么意义,因为那样你就永远看不到它的结尾。
我们倾向于保持乐观(简单的东西会起作用),我们测试更复杂的关联,如果我们在映射中遇到错误(例如应该删除但没有删除的对象),我们会编写一个额外的测试为了那个原因。
从业务角度对所有内容进行绝对测试通常是不明智的。你应该首先关注高风险/高伤害的东西,然后沿着严重程度的阶梯往下走,直到你认为它不再值得了。

于 2012-08-30T10:59:49.017 回答
0

1)有一组集成测试来测试你的映射

2)使您的 DAL重量非常轻,但具有足够的能力来构建查询,例如:

public interface IDb
{
    IQueryable<T>Query<T>();
    ... (save, delete, get-by-id methods)...
}

3) 编写对象,这些对象封装了针对 DAL 构建查询背后的逻辑

public class MuppetSearch
{
    public MuppetColor? Color { get; set;}
    public string Name{ get; set; }
    public IQueryable<Muppet> ConstructQuery(IDb db)
    {
        var query = db.Query<Muppet>();
        if(Color.HasValue)
        {
            query = query.Where(m=>m.Value == Color.Value);
        }
        if(!String.IsNullOrEmpty(Name))
        {
            query = query.Where(m=>m.Name.Contains(Name));
        }
        return query;
    }
}

4)测试那些,模拟你需要的所有数据应该很简单

5)在您的服务中使用搜索类来进行查询构建

于 2012-08-30T14:01:37.947 回答
0

实体框架经过测试,但您的 DAL,尤其是映射,没有。我更喜欢进行集成测试,以向我展示至少我的映射是正确的,而且更好的是,我可以成功地对我的数据库执行所有 CRUD 操作。

于 2012-08-30T06:49:24.820 回答