Модульное тестирование ServiceLayer с лямбда и Moq - PullRequest
1 голос
/ 10 октября 2011

Я пытаюсь проверить лямбду, которая используется в моем хранилище моим сервисным слоем, используя Moq.

Служба:

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 ]

4 голосов
/ 10 октября 2011

Мы используем ту же технику. Вы можете захватить выражение, передаваемое при настройке макета, например

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 голос
/ 10 октября 2011

Ваш фиктивный репозиторий был настроен для возврата обеих компаний, поэтому вы возвращаете их обе.

Вам следует написать модульный тест для репозитория, чтобы проверить, что лямбды выполняются правильно.На уровне сервиса модульному тестированию нужно только проверить, что хранилище было вызвано с правильными параметрами.

0 голосов
/ 10 октября 2011

Вы настраиваете свой фиктивный метод Find для возврата списка из двух объектов, проверка userId внутри поставляемой лямбды обходится этой установкой

...