MV3 Test Project с Moq, как вернуть объект, когда используется определенное выражение? - PullRequest
2 голосов
/ 17 февраля 2012

Вот мой код:

    [TestMethod]
    public void LoginUnregisteredUserShouldFail()
    {
        Mock<IRepository<User>> _repo = new Mock<IRepository<User>>();
        UserServiceForTest target = new UserServiceForTest(_repo.Object, new HashingService());

        var unregisteredTestUser = new User() { Email = "a", Nombre = "test", Password = "test" };
        var registeredHashedTestUser = new User() { Email = "test@test.com", Nombre = "test", Password = "qUqP5cyxm6YcTAhz05Hph5gvu9M=" };
        Expression<Func<User, bool>> expression = a => a.Email == "a";
        _repo.Setup(a => a.Single(It.Is<Expression<Func<User,bool>>>(l => l.ToString() == expression.ToString()))).Returns(unregisteredTestUser);
        Assert.IsFalse(target.ValidateCredentials(unregisteredTestUser));
    }

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

Я незнаю, что я делаю неправильно, но я всегда получаю ноль.

РЕДАКТИРОВАТЬ: моя реализация следующая:

    private string GetUserPasswordFromDbByUserName(string userName)
    {
        Expression<Func<User, bool>> ax = a => a.Email == userName;
        var axx = ax.ToString();
        var user = _repo.Single(ax);
        if (user != null)
            return user.Password;
        else
            return string.Empty;
    }

Он получает строку userName и по какой-то причине .ToString () возвращает 'a => (a.Email == значение (Casita.Services.UserService + <> c__DisplayClass5) .userName) "вместо" a => (a.Email == "a")'.Не имеет смысла для меня, но я предполагаю, что это причина, по которой сравнение не удается.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2012

Еще один (слабый) способ проверить это - передать выражение в список и позволить Linq To Objects вернуть то, что он может.Опять же, вы не получите точно такое же поведение от linq к объектам, как и от Linq2Sql, Linq2EF или чего-то еще, но ...

в любом случае вот оно:

        List<User> users = new List<User>() 
        { 
            new User { Email = "a" }, 
            new User { Email = "b" } 
        };

        _repo.Setup(a => a.Single(It.IsAny<Expression<Func<User, bool>>>()))
            .Returns<Expression<Func<User, bool>>>(predicate => users.AsQueryable()
                .Where(predicate).SingleOrDefault());

это, что бы ни передавалось методу Single, передавалось бы методу Where в списке ...

2 голосов
/ 17 февраля 2012

Ваша проблема, вероятно, в сравнении равенства в параметре выражения Is. Они, вероятно, не совпадают при преобразовании в строки, поэтому сравнение на равенство может быть неудачным. Следующий вопрос подробно описывает, как сравнивать делегаты [Func]:

Как проверить, совпадают ли два выражения >

Конечно, я предполагаю, что может сработать следующее. Обратите внимание, что это будет использовать http://evain.net/blog/articles/2008/02/06/an-elegant-linq-to-db4o-provider-and-a-few-linq-tricks, что может потребовать добавления ссылки / загрузки db4o. На этом я прекратил исследования.

Func<Expression, Expression, bool> eq =
                ExpressionEqualityComparer.Instance.Equals;

Expression<Func<User, bool>> expression = a => a.Email == "a";
        _repo.Setup(a => a.Single(It.Is<Expression<Func<User,bool>>>(l => eq(l,expression))).Returns(unregisteredTestUser);

Во всяком случае, основная проблема, вероятно, заключается в таком сравнении.

Ответ Марка Гравелла, по-видимому, подразумевает использование метода, который вы используете, будет работать, но только если все, включая переменные в реализации вашего фактического метода, в точности совпадают и передаются в том же состоянии при вызове зависимости репозитория.

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

Я бы попробовал отладку и просмотр каждого выражения, преобразованного в строку (одно в вашем тестовом методе и другое в вашей реализации, и проверил бы, точно ли они совпадают. Если это так, то эта теория выходит за рамки. )

Это ослабляет ваш тест, но вы можете просто проверить, передано ли любое выражение и вернуть то, что вы хотите.

Другая альтернатива, которая может работать для вас, это проверка того, совпадают ли результаты делегатов, но опять-таки это более слабый тест:

_repo.Setup(a => a.Single(It.Is<Expression<Func<User,bool>>>(l = l(unregisteredTestUser)== expression(unregisteredTestUser)))).Returns(unregisteredTestUser);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...