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