我有一个像这样的通用存储库:
public interface IRepository<TEntity> where TEntity :class
{
IEnumerable<TEntity> SearchFor(Expression<Func<TEntity, bool>> filter);
TEntity GetById(int id);
void Insert(TEntity entity);
void Delete(TEntity entity);
void Update(TEntity entity);
}
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity: class
{
private DbSet<TEntity> _dbSet; // put the entity specified in place of TEntity in d DbSet so i can query the entity e.g School Entity
private NaijaSchoolsContext _naijaSchoolsContext;
public GenericRepository(NaijaSchoolsContext context)
{
_naijaSchoolsContext = context;
_dbSet = _naijaSchoolsContext.Set<TEntity>(); //return the entity specified in the TEntity and put it in DbSet
}
public IEnumerable<TEntity> SearchFor(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter)
{
return _dbSet.Where(filter);
}
public TEntity GetById(int id)
{
return _dbSet.Find(id);
}
public void Insert(TEntity entity)
{
_dbSet.Add(entity);
}
public void Delete(TEntity entity)
{
_dbSet.Remove(entity);
}
public void Update(TEntity entity)
{
_dbSet.AddOrUpdate(entity);
}
}
我也有这样的UoW:
public interface IUnitofWork : IDisposable
{
void Save();
}
public class UnitofWork : IUnitofWork
{
NaijaSchoolsContext naijaSchoolsContext = new NaijaSchoolsContext();
private GenericRepository<School> schoolRepository;
private bool isDisposed = false;
public GenericRepository<School> SchoolRepository
{
get
{
if (schoolRepository == null)
{
schoolRepository = new GenericRepository<School>(naijaSchoolsContext);
}
return schoolRepository;
}
}
public void Save()
{
naijaSchoolsContext.SaveChanges();
}
public void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
naijaSchoolsContext.Dispose();
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
我的测试类看起来像这样:
[TestFixture]
public class when_working_with_school_repository
{
}
public class and_saving_a_school : when_working_with_school_repository
{
private School _returnedSchool;
private School _school;
private Mock<IRepository<School>> _repository;
private Exception _result;
[SetUp]
private void SetUp()
{
_repository = new Mock<IRepository<School>>();
_school = new School();
}
[Test]
public void then_a_valid_school_should_be_saved()
{
_repository.Setup(s => s.Insert(_school));
//_returnedSchool = _schoolRepository.Save(_school);
}
[Test]
public void should_throw_an_exception_when_no_school_is_saved()
{
try
{
_repository.Setup(s => s.Insert(null));
}
catch (Exception exception)
{
_result = exception;
}
}
[Test]
public void should_notify_user_if_school_name_already_exists()
{
//bool exists = _schoolRepository.IsExist(_school.Name);
}
}
我的测试通过,但我担心的是
答案 0 :(得分:0)
我认为你最好嘲笑IRepository。但是,你的测试将通过,因为你没有断言任何事情。
我认为您需要设置您的模拟以获得所需的结果。这是一个修改过的例子:
[Test]
public void then_a_valid_school_should_be_saved()
{
var _school = new School { .... };
var expected = _school.Id;
_repository.Setup(s => s.Insert(_school));
_repository.Setup(s => s.GetById(_school.Id)).Returns(_school);;
_repository.Insert(_school);
var actual = _repository.GetById(_school.Id);
Assert.Equal(expected, actual);
}
应该这样做。要使测试失败,请尝试为预期结果添加不同的Id并验证其是否有效。您可以使用它来改进您的其他测试。
答案 1 :(得分:0)
不,你不是。您正在测试 mock :
_repository = new Mock<IRepository<School>>();
您想要测试您的代码,而不是其他人。您的通用存储库只是将调用委托给_dbSet
。这就是你想要测试的 - 调用是委托的(这是一种包装功能)。
怎么做?您需要对DbSet<T>
进行抽象,这是您在测试中模拟的对象。您的所有测试看起来都相似:
var dbSetMock = new Mock<DbSet<School>>();
var context = new Mock<Context>();
var repository = new GenericRepository<School>(dbSetMock, context);
repository.FindBy(arg);
dbSetMock.Verify(d => d.FindBy(arg));
这需要对DbSet
和您的自定义上下文进行抽象,以使其正常工作。