【问题标题】:Unit Testing a Base Service with Entity Framework 6使用 Entity Framework 6 对基础服务进行单元测试
【发布时间】:2014-12-03 08:58:14
【问题描述】:

我有一个我的服务通常继承自的基本服务类,看起来像这样

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 进行单元测试?唯一的问题是,baseService 是抽象的,所以为了测试它,我需要创建一个继承自它的类,以便对其进行测试。

我是单元测试的新手,如果有一个明显的答案,很抱歉。

【问题讨论】:

    标签: c# .net unit-testing inheritance testing


    【解决方案1】:

    是的

    一般来说,您确实确实希望根据基础合同测试每个后代。毕竟,任何被覆盖的方法都可能包含使/矛盾/......此类层次结构的客户所期望的基本行为的代码。而且您不希望这种情况发生,因此您需要针对每个基本服务的后代进行单元测试的早期警报系统。

    这也称为“合同测试”。

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

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

    【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多