看到一些针对模拟测试 EF 的强烈建议,尤其是 Code First,我决定对专用于测试的 SqlCe 数据库进行集成测试,然后在 DbContext 提供的工作单元和存储库的下游使用纯单元测试和数据库集。
我只是不清楚在哪里画线以及在哪里测试什么。我知道当我确信 DAL 特定的集成测试涵盖了它的内部时,我可以在我的服务层中模拟 DAL,但是我在 DAL 中测试什么?似乎没有太多意义的测试来查看我是否可以保存和读取对象,因为 EF 是外部的并且已经过测试。
看到一些针对模拟测试 EF 的强烈建议,尤其是 Code First,我决定对专用于测试的 SqlCe 数据库进行集成测试,然后在 DbContext 提供的工作单元和存储库的下游使用纯单元测试和数据库集。
我只是不清楚在哪里画线以及在哪里测试什么。我知道当我确信 DAL 特定的集成测试涵盖了它的内部时,我可以在我的服务层中模拟 DAL,但是我在 DAL 中测试什么?似乎没有太多意义的测试来查看我是否可以保存和读取对象,因为 EF 是外部的并且已经过测试。
您将使用集成测试在 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
依赖于DAL
。DAL
接口通过构造函数注入传递。Service
包含您想要测试以了解逻辑是否正确执行的公共 DoSomething 方法。但是这种方法也依赖于数据库查询和数据库持久性(Commit
)。Service
该类(存储库)中。这些查询方法的关键标准是:
IQueryable
Expression<>
作为参数如何单元测试DoSomething
方法:
Service
类派生并覆盖FindSomeData
以返回测试数据。在注入的情况下,您将改为为注入的类定义假。IDAL
,您可以验证是否Commit
已调用您应该使用什么集成测试:
FindSomeData
您应该为查询真实数据库创建测试Commit
但实现起来更加困难,因为该示例直接从DoSomething
. 您不想再次测试该方法,并且同时Commit
方法具有太多通用案例,因为它只是将所有更改从当前上下文刷新到数据库。我通常对插入、更新和删除每个实体类型进行单独的测试。当该DoSomething
方法进行一些复杂的修改时,您可以将该方法拆分为两种方法,一种由单元测试处理,用于真实逻辑,另一种由集成测试覆盖,用于您的逻辑可以产生的不同持久性场景。我们通常在 DB 方面测试的是复杂对象图是否可以正确插入、更新、删除;基本上测试更复杂的映射。
在我看来,测试是否可以插入具有 3 个原始值属性的对象并没有什么意义,因为那样你就永远看不到它的结尾。
我们倾向于保持乐观(简单的东西会起作用),我们测试更复杂的关联,如果我们在映射中遇到错误(例如应该删除但没有删除的对象),我们会编写一个额外的测试为了那个原因。
从业务角度对所有内容进行绝对测试通常是不明智的。你应该首先关注高风险/高伤害的东西,然后沿着严重程度的阶梯往下走,直到你认为它不再值得了。
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)在您的服务中使用搜索类来进行查询构建
实体框架经过测试,但您的 DAL,尤其是映射,没有。我更喜欢进行集成测试,以向我展示至少我的映射是正确的,而且更好的是,我可以成功地对我的数据库执行所有 CRUD 操作。