2014-12-03 74 views
0

我有一个基本服务类,我的服务通常由继承,看起来像这样单元测试基本服务实体框架6

public abstract class BaseService<TEntity> 
    where TEntity : class, IBaseEntity 
{ 
    protected DataContext _context; 

    protected BaseService(DataContext context) 
    { 
     _context = context; 
    } 

    public virtual async Task<ICollection<TEntity>> GetAllAsync() 
    { 
     return await _context.Set<TEntity>().ToListAsync(); 
    } 

    public virtual Task<TEntity> GetAsync(long id) 
    { 
     return _context.Set<TEntity>().FindAsync(id); 
    } 

    public virtual Task<int> AddAsync(TEntity t) 
    { 
     if (_context.Entry(t).State == EntityState.Detached) 
     { 
      _context.Set<TEntity>().Add(t); 
     } 

     _context.Entry(t).State = EntityState.Added; 

     return _context.SaveChangesAsync(); 
    } 

    public virtual Task<int> AddAllAsync(ICollection<TEntity> all) 
    { 
     foreach (var item in all) 
     { 
      if (_context.Entry(item).State == EntityState.Detached) 
      { 
       _context.Set<TEntity>().Add(item); 
      } 

      _context.Entry(item).State = EntityState.Added; 
     } 

     return _context.SaveChangesAsync(); 
    } 

    public virtual Task<int> UpdateAsync(TEntity updated) 
    { 
     _context.Entry(updated).State = EntityState.Modified; 

     return _context.SaveChangesAsync(); 
    } 

    public virtual Task<int> DeleteAsync(long key) 
    { 
     return DeleteAsync(key, true); 
    } 

    public virtual async Task<int> DeleteAsync(long key, bool useFlag) 
    { 
     TEntity entity = await GetAsync(key); 
     return await DeleteAsync(entity, useFlag); 
    } 

    public virtual Task<int> DeleteAsync(TEntity t) 
    { 
     return DeleteAsync(t, true); 
    } 

    public virtual Task<int> DeleteAsync(TEntity t, bool useFlag) 
    { 
     // check if the object uses IAuditableEntity 
     IAuditableEntity auditable = t as IAuditableEntity; 

     if (useFlag && auditable != null) 
     { 
      // flag item as deleted 
      auditable.IsDeleted = true; 

      return UpdateAsync(t); 
     } 
     else 
     { 
      _context.Entry(t).State = EntityState.Deleted; 

      return _context.SaveChangesAsync(); 
     } 
    } 

} 

现在,如果我需要在从继承的类覆盖的方法它,我可以做到这一点。

我的问题是这些方法应该在每个从BaseService类继承的每个类的单元测试中进行测试,还是我应该只测试单元测试我覆盖的方法并对基本服务进行单元测试?只有这样,baseService是抽象的,所以为了测试它,我需要创建一个继承它的类,以便测试它。

我是新来的单元测试,所以很抱歉,如果这是一个明显的答案。

回答

0

是的

一般来说,你确实要测试每个后代对基地的合同。毕竟任何重写的方法都可以包含使这个类层次结构的客户端期望的基本行为无效/违反的代码。你不希望这种情况发生,所以你需要为每个基础服务的后代提供单元测试的早期报警系统。

这也被称为“合同测试”。

实现它的方法之一是创建一个(n抽象)单元测试类来验证基类的行为,然后为其每个后代派生(具体)单元测试类。所有那些具体的单元测试类应该做的就是设置被测试的实例 - 这是后代类的一个实例。然后,继承应该照顾基础单元测试类中定义的测试方法对后代实例的运行。

如果基类是抽象的,你仍然可以在你的基类中编写你的单元测试类。通过标记这个单元测试类抽象,你也确保测试运行器不会实例化它来运行它的测试。它只会“发现和运行”从它派生出来的具体测试类来测试基地的后代。

+0

明目张胆的自我推销:我刚刚写了一篇关于如何为小型课堂层次做到这一点的博客文章[如何测试一个类层次结构而不重复自己](http://softwareonastring.com/2015/03/15/how -to-测试一个类层次结构,而无需重复的自己动手)。 – 2015-03-15 20:13:15