2

A具有与一个典型的场景数据访问层(DAL)的应用程序:与实体框架(EF)创建库测试最小化的重复

  • 数据上下文。
  • 使用由EF生成的实体用作整个应用程序的通用DTO。
  • DAL包含扩展RepositoryBase抽象类的不同存储库,该类实现基本的CRUD操作;特定的存储库只有其实体类型的特定方法。可以软删除的实体的存储库扩展了SoftDeleteRepositoryBase,它本身扩展了RepositoryBase。

为了给出一些上下文,下面是一些类/接口。

通用仓库接口:

public interface IRepository<T> : IDisposable where T : class 
{ 
    void Add(T entity); 
    void Update(T entity); 
    void Obliterate(T entity); 
    void Obliterate(Expression<Func<T, bool>> where); 
    T GetById(long id); 
    T GetById(string id); 
    IQueryable<T> GetAll(); 
    IQueryable<T> GetMany(Expression<Func<T, bool>> where); 
    T GetSingle(Expression<Func<T, bool>> where); 
    void SaveChanges(); 
} 

库基地:

public abstract class RepositoryBase<T> : IRepository<T> where T : class 
{ 
    ... 
} 

一个为Foo实体库:

public class FooRepository : RepositoryBase<File>, IFooRepository 
{ 
    // Specific methods here 
    ... 
} 

我应该如何测试库?现在,我为每个存储库都有一个测试类,其中所有测试方法都非常相似,因为它们大多数都是从RepositoryBase中测试通用方法。很明显,我需要针对特定​​方法进行测试,但是对于全局通用方法,我是否应该针对每个不同的实体进行测试?我不知道假设插入是否适用于Foo实体是否明智也适用于其他人;然而,对于每个测试而言,在测试创建和维护方面都有额外的开销。你能推荐任何有关这方面的最佳做法吗?

(顺便说一句,这些都是集成测试)

感谢

+4

湮没?这是我第一次看到Obliterate而不是删除或删除 –

+0

还有另一个工具已经使用这个名字,我们的用户非常熟悉它;加上它让你在调用它之前三思考:)可以被软删除的实体有一个Delete方法。 – chuwik

+0

'IQueryable '不属于存储库。在这里阅读其他一些关于为什么的问题。 – jgauffin

回答

2

我不知道这是否是明智的假设,如果插入,例如, 作品Foo的实体也将为他人工作

不,你不能假设这一点。如果某个实体没有正确的映射会怎么样?如果您忘记在您的DbContext上定义DbSet<Bar>,该怎么办?如果你想完全确定,你应该测试所有具体存储库的所有方法。

但是每个测试在测试 创建和维护

正确方面的额外开销。这就是为什么而不是仅为存储库编写集成测试的原因,请为您的应用程序编写验收测试。您将练习整个堆栈,并将涉及具体的存储库。

+0

我明白你的意思与验收测试;然而,这个应用程序只是一个DAL,作为一个库分发,其他同行将在他们的应用程序中使用它来访问我们的系统。所以测试真的不多 – chuwik