使用通用存储库/UnitOfWork 进行模拟
Mocking with Generic Repository / UnitOfWork
如何从通用存储库和服务中测试插入方法?
我有这个通用存储库:
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
TEntity GetById(object id);
IEnumerable<TEntity> GetAll();
void Insert(TEntity entity);
void Delete(object id);
void Delete(TEntity entityToDelete);
void Update(TEntity entityToUpdate);
本作业单元:
IGenericRepository<Department> DepartmentRepository { get; }
和这项服务
public void Insert(string depName, List<Post> posts = null)
{
try
{
var department = new Department(depName, posts);
unitOfWork.DepartmentRepository.Insert(department);
unitOfWork.Save();
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
return;
}
}
我想用 Rhino.Mock
测试这个服务方法
var mocks = new MockRepository();
IUnitOfWork unitOfWork = mocks.Stub<IUnitOfWork>();
Department dep = new Department("test");
var id = Guid.NewGuid().ToString();
unitOfWork.Expect(svc => svc.DepartmentRepository.Insert(dep));
unitOfWork.Expect(svc => svc.Save());
DepartmentService depService = new DepartmentService(unitOfWork);
// Act
mocks.ReplayAll();
depService.Insert(dep.Name);
var result = depService.GetAll();
而且我总是出错,有人可以帮助我吗?
错误:
"IUnitOfWork.get_DepartmentRepository(); Expected #1, Actual #2."
有几件事应该做得更好:
- 可以通过静态
MockRepository.GenerateMock
方法创建模拟实例(您使用的存储库实例是旧的 API)
DepartmentRepository
属性 应该被嘲笑为 Insert
将进行调用验证
mocks.ReplayAll()
不需要
- 不需要调用
depService.GetAll()
- 在您的测试中,您将 插入 数据到 mocks,它不会在任何地方插入任何东西,因此提取 已插入 数据不会产生任何结果
考虑到以上几点,您的测试应该更接近于此:
// Arrange
// 1. Instantiate mocks
var unitOfWork = MockRepository.GenerateMock<IUnitOfWork>();
var repository = MockRepository.GenerateMock<IGenericRepository<Department>>();
// 2. Setup unit of work to return mocked repository
unitOfWork.Stub(uow => uow.DepartmentRepository).Returns(repository);
// 3. Setup expectations - note that we ignore Department argument
repository.Expect(rep => rep.Insert(Arg<Department>.Is.Anything));
unitOfWork.Expect(uow => uow.Save());
var dep = new Department("test");
var depService = new DepartmentService(unitOfWork);
// Act
depService.Insert(dep.Name);
// Assert
repository.VerifyAllExpectations();
unitOfWork.VerifyAllExpectations();
几乎没有什么可以改进的 -- 例如,Insert
调用的参数匹配。我把它留给你。
如何从通用存储库和服务中测试插入方法? 我有这个通用存储库:
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
TEntity GetById(object id);
IEnumerable<TEntity> GetAll();
void Insert(TEntity entity);
void Delete(object id);
void Delete(TEntity entityToDelete);
void Update(TEntity entityToUpdate);
本作业单元:
IGenericRepository<Department> DepartmentRepository { get; }
和这项服务
public void Insert(string depName, List<Post> posts = null)
{
try
{
var department = new Department(depName, posts);
unitOfWork.DepartmentRepository.Insert(department);
unitOfWork.Save();
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
return;
}
}
我想用 Rhino.Mock
var mocks = new MockRepository();
IUnitOfWork unitOfWork = mocks.Stub<IUnitOfWork>();
Department dep = new Department("test");
var id = Guid.NewGuid().ToString();
unitOfWork.Expect(svc => svc.DepartmentRepository.Insert(dep));
unitOfWork.Expect(svc => svc.Save());
DepartmentService depService = new DepartmentService(unitOfWork);
// Act
mocks.ReplayAll();
depService.Insert(dep.Name);
var result = depService.GetAll();
而且我总是出错,有人可以帮助我吗? 错误:
"IUnitOfWork.get_DepartmentRepository(); Expected #1, Actual #2."
有几件事应该做得更好:
- 可以通过静态
MockRepository.GenerateMock
方法创建模拟实例(您使用的存储库实例是旧的 API) DepartmentRepository
属性 应该被嘲笑为Insert
将进行调用验证mocks.ReplayAll()
不需要- 不需要调用
depService.GetAll()
- 在您的测试中,您将 插入 数据到 mocks,它不会在任何地方插入任何东西,因此提取 已插入 数据不会产生任何结果
考虑到以上几点,您的测试应该更接近于此:
// Arrange
// 1. Instantiate mocks
var unitOfWork = MockRepository.GenerateMock<IUnitOfWork>();
var repository = MockRepository.GenerateMock<IGenericRepository<Department>>();
// 2. Setup unit of work to return mocked repository
unitOfWork.Stub(uow => uow.DepartmentRepository).Returns(repository);
// 3. Setup expectations - note that we ignore Department argument
repository.Expect(rep => rep.Insert(Arg<Department>.Is.Anything));
unitOfWork.Expect(uow => uow.Save());
var dep = new Department("test");
var depService = new DepartmentService(unitOfWork);
// Act
depService.Insert(dep.Name);
// Assert
repository.VerifyAllExpectations();
unitOfWork.VerifyAllExpectations();
几乎没有什么可以改进的 -- 例如,Insert
调用的参数匹配。我把它留给你。