2013-03-19 117 views
2

我是Moq和单元测试新手。我想用实体框架5来测试我的Repository和Unit of Work模式。但我不明白我在哪里以及如何开始。如何在实体框架中模拟存储库和工作模式单元?

我的仓库接口:

public interface ISmRepository<T> 
{ 
    void Add(T entity); 
    void Remove(T entity); 
    void Update(T entity); 
    IQueryable<T> SearchFor(Expression<Func<T, bool>> expression); 
    IQueryable<T> GetAll(); 
    T GetById(Int64 id); 
} 

我的仓库:

public class SmReporitory<T> : ISmRepository<T> where T : class, IEntity, new() 
{ 
    private readonly DbSet<T> _dbSet; 
    private readonly DbContext _dbContext; 

    public SmReporitory(DbContext dbContext) 
    { 
     _dbSet = dbContext.Set<T>(); 
     _dbContext = dbContext; 
    } 

    public void Add(T entity) 
    { 
     _dbSet.Add(entity); 
    } 

    public void Remove(T entity) 
    { 
     _dbSet.Remove(entity); 
    } 

    public void Update(T entity) 
    { 
     _dbContext.Entry(entity).State = EntityState.Modified; 
    } 

    public IQueryable<T> SearchFor(Expression<Func<T, bool>> expression) 
    { 
     return _dbSet.Where(expression); 
    } 

    public IQueryable<T> GetAll() 
    { 
     return _dbSet; 
    } 

    public T GetById(long id) 
    { 
     return _dbSet.FirstOrDefault(x => x.Id == id); 
    } 
} 

我单位工作界面:

public interface ISmUnitOfWork : IDisposable 
{ 
    ISmRepository<BreakdownCause> BreakdownCasus { get; } 
    ISmRepository<BreakDownType> BreakDownTypes { get; } 
    ISmRepository<CompanyInformation> CompanyInformations { get; } 
    void Save(); 
} 

我单位工作执行情况:第

public class SmUnitOfWork : ISmUnitOfWork 
{ 
    private readonly DbContext _dbContext; 
    private ISmRepository<BreakDownType> _breakDownTypes; 
    private ISmRepository<BreakdownCause> _breakdownCasus; 
    private ISmRepository<CompanyInformation> _companyInformations; 

    public SmUnitOfWork() : this(new SmDbContext()) 
    { 
    } 

    public SmUnitOfWork(SmDbContext smDbContext) 
    { 
     _dbContext = smDbContext; 
    } 

    public ISmRepository<BreakdownCause> BreakdownCasus 
    { 
     get { return _breakdownCasus ?? (_breakdownCasus = new SmReporitory<BreakdownCause>(_dbContext)); } 
    } 

    public ISmRepository<BreakDownType> BreakDownTypes 
    { 
     get { return _breakDownTypes ?? (_breakDownTypes = new SmReporitory<BreakDownType>(_dbContext)); } 
    } 

    public ISmRepository<CompanyInformation> CompanyInformations 
    { 
     get { return _companyInformations ?? (_companyInformations = new SmReporitory<CompanyInformation>(_dbContext)); } 
    } 
    public void Save() 
    { 
     try 
     { 
      _dbContext.SaveChanges(); 
     } 
     catch 
     { 
      throw; 
     } 
    } 
    public void Dispose() 
    { 
     if (_dbContext!=null) 
     { 
      _dbContext.Dispose(); 
     } 
    } 

现在我想测试ISmRepository接口方法的。

我已经在类库项目中引用了NUnit和Moq。现在我需要一个起点。

回答

0

简短的回答是,你真的不能。至少不完全。原因是moq'd EF上下文的行为与真实的上下文sql翻译不同。

有很多代码会通过Moq'd的上下文,但会炸毁一个真实的代码。因此,您不能依靠摩青在EF环境下的假货,而必须使用集成测试。

+0

好的。可以告诉我如何测试我的SmRepository抛出ISmUnitOfWork。 – 2013-03-19 17:32:20

3

你真的不需要测试你的存储库,因为你有他们写的。原因是,正如Mystere Man暗示的那样,你基本上只是包装了Entity Framework API。在使用EF并使用我自己的存储库或某些DbContext时,我不担心测试这些数据访问调用,直到集成测试时间出于上述原因。

但是,您可以(也应该)嘲笑您的存储库和工作单元,以测试所有其他依赖于它们的代码。通过测试你的存储库,你真的测试了Entity Framework的功能,我相信这已经被测试得比你想象的更彻底。您可以做的一件事就是不要将业务逻辑放入与EF直接交互的存储库中,而是将其移至另一个使用存储库进行数据访问的层。

+0

完全同意,并说得好! +1的答案 – Spock 2013-07-06 08:00:28