如何在实体框架中模拟存储库和工作单元模式
本文关键字:工作 单元 模式 存储 模拟 实体 框架 | 更新日期: 2023-09-27 18:04:38
我是Moq和单元测试的新手。我想测试我的存储库和工作单元模式与实体框架5。但是我不知道从哪里开始,怎样开始。
My Repository Interface:
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);
}
}
My Unit Of Work接口:
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。现在我需要一个起始点
您真的不需要在编写存储库时对其进行测试。原因是,正如mysterman所暗示的,你基本上只是包装实体框架API。当使用EF并使用我自己的存储库或一些DbContext
时,我不担心在集成测试时间之前测试这些数据访问调用,原因已经说明了。
但是,您可以(也应该)模拟您的存储库和工作单元来测试所有依赖于它们的其他代码。通过测试你的存储库,你实际上是在测试实体框架的功能,我相信它已经被测试得比你想象的更彻底了。您可以做的一件事是不要将业务逻辑放入直接与EF交互的存储库中,而是将其移到利用存储库进行数据访问的另一层。
简短的回答是,你真的不能。至少不完全是这样。这样做的原因是,由于固有的sql转换,模拟的EF上下文的行为与真实的上下文不同。
有很多代码会传递一个Moq的上下文,但在一个真正的上下文中会爆炸。因此,您不能依赖于EF上下文的Moqing of fakes,您必须使用集成测试。