2013-03-19 116 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