使用 lambda 和 Moq 对 ServiceLayer 进行单元测试
我正在尝试使用 Moq 测试我的服务层在我的存储库上使用的 lambda。
服务:
public class CompanyService : TuneUpLog.ServiceLayer.ICompanyService
{
private IRepository<Company> _repository;
private IValidationDictionary _validatonDictionary;
private Guid _userId;
public CompanyService(Guid userId,IValidationDictionary validationDictionary, ObjectContext context)
: this(userId, validationDictionary, new Repository<Company>(context))
{
}
public CompanyService(Guid userId, IValidationDictionary validationDictionary, IRepository<Company> repository)
{
_validatonDictionary = validationDictionary;
_repository = repository;
if (userId == Guid.Empty)
throw new SecurityException("UserId is required");
else
_userId = userId;
}
public IEnumerable<Company> ListCompany()
{
return _repository.Find(c => c.Users.Any(u => u.UserId == _userId));
}
}
测试:
[TestMethod]
public void ListCompany_1Valid1Invalid_ReturnsValidCompany()
{
Mock<IRepository<Company>> fakeCompanyRepository = new Mock<IRepository<Company>>();
CompanyService companyService = new CompanyService(USER_ID, new ModelStateWrapper(_modelState), fakeCompanyRepository.Object);
//1 company for this user and 1 that isn't for this user
List<Company> companies = new List<Company>()
{
new Company() { Id = 1, Name = "Test Company", AccountTypeId = 1, Users = { new User() { UserId = USER_ID } } },
new Company() { Id = 2, Name = "2nd Test Company", AccountTypeId = 1, Users = { new User() { UserId = Guid.Empty } } }
};
fakeCompanyRepository.Setup(c => c.Find(It.IsAny<Expression<Func<Company, bool>>>())).Returns(companies.AsQueryable());
//count should be 1
Assert.AreEqual(1, companyService.ListCompany().Count());
}
存储库:
public interface IRepository<T> where T : class, IEntity
{
void Add(T newEntity);
void Edit(T entity);
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
IQueryable<T> FindAll();
T FindById(int id);
void Remove(T entity);
void Attach(T entity);
}
测试返回两家公司,而不是我期望的第一家公司。我做错了什么?
I am trying to test a lambda that is used on my repository by my service layer using Moq.
The Service:
public class CompanyService : TuneUpLog.ServiceLayer.ICompanyService
{
private IRepository<Company> _repository;
private IValidationDictionary _validatonDictionary;
private Guid _userId;
public CompanyService(Guid userId,IValidationDictionary validationDictionary, ObjectContext context)
: this(userId, validationDictionary, new Repository<Company>(context))
{
}
public CompanyService(Guid userId, IValidationDictionary validationDictionary, IRepository<Company> repository)
{
_validatonDictionary = validationDictionary;
_repository = repository;
if (userId == Guid.Empty)
throw new SecurityException("UserId is required");
else
_userId = userId;
}
public IEnumerable<Company> ListCompany()
{
return _repository.Find(c => c.Users.Any(u => u.UserId == _userId));
}
}
The Test:
[TestMethod]
public void ListCompany_1Valid1Invalid_ReturnsValidCompany()
{
Mock<IRepository<Company>> fakeCompanyRepository = new Mock<IRepository<Company>>();
CompanyService companyService = new CompanyService(USER_ID, new ModelStateWrapper(_modelState), fakeCompanyRepository.Object);
//1 company for this user and 1 that isn't for this user
List<Company> companies = new List<Company>()
{
new Company() { Id = 1, Name = "Test Company", AccountTypeId = 1, Users = { new User() { UserId = USER_ID } } },
new Company() { Id = 2, Name = "2nd Test Company", AccountTypeId = 1, Users = { new User() { UserId = Guid.Empty } } }
};
fakeCompanyRepository.Setup(c => c.Find(It.IsAny<Expression<Func<Company, bool>>>())).Returns(companies.AsQueryable());
//count should be 1
Assert.AreEqual(1, companyService.ListCompany().Count());
}
The Repository:
public interface IRepository<T> where T : class, IEntity
{
void Add(T newEntity);
void Edit(T entity);
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
IQueryable<T> FindAll();
T FindById(int id);
void Remove(T entity);
void Attach(T entity);
}
The Test is returning both companies instead of the 1st company that I expect. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我们使用相同的技术。您可以在设置模拟时捕获传入的表达式,如下所示
这会将您的表达式应用于公司集合。
We use the same technique. You can capture the Expression being passed in when setting up the mock like so
This will apply your expression to the companies collection.
您的模拟存储库已设置为返回这两家公司,这就是您将它们都返回的原因。
您应该为存储库编写一个单元测试,以检查 lambda 是否正确执行。在服务层,单元测试只需要验证是否使用正确的参数调用了存储库。
Your mock repository has been set up to return both the companies, which is why you get them both back.
You should be writing a unit test for the repository to check that the lambdas are executed correctly. In the service layer, the unit test only needs to verify that the repository has been called with the correct parameters.
您正在设置模拟 Find 方法以返回两个对象的列表,此设置绕过了提供的 lambda 内的 userId 检查
You're setting up your mock Find method to return a list of two objects, the userId check inside the lambda supplied is bypassed by this setup