单元测试ServiceLayer与lambda和Moq

时间:2011-10-10 12:54:44

标签: c# unit-testing mocking moq

我正在尝试使用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);
}

测试正在回归两家公司而不是我期望的第一家公司。我做错了什么?

3 个答案:

答案 0 :(得分:4)

我们使用相同的技术。您可以捕获在设置模拟时传入的表达式

fakeCompanyRepository.Setup(
  u => u.Find(It.IsAny<Expression<Func<Company, bool>>>()))
  .Returns(
     //Capture the It.IsAny parameter
     (Expression<Func<Company, bool>> expression) => 
     //Apply it to your queryable.
        companies.AsQueryable().Where(expression));

这会将您的表达应用于公司集合。

答案 1 :(得分:1)

您的模拟存储库已经设置为返回两家公司,这就是为什么你们都回来了。

您应该为存储库编写单元测试,以检查lambdas是否正确执行。在服务层中,单元测试只需要验证是否已使用正确的参数调用存储库。

答案 2 :(得分:0)

您正在设置模拟Find方法以返回两个对象的列表,此设置绕过了所提供的lambda内的userId检查