Мок с лямбда-выражениями? - PullRequest
3 голосов
/ 10 июня 2011

Я пытаюсь протестировать службу приложений, используя Moq 4.0.10827 (на NuGet), и мне нужно запросить хранилище:

public class MyService
{
    Repository<MyObject> _Repo;

    public MyObject Get (string SomeConstraint)
    {
        return _Repo
            .GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (
                SomeContraint, StringComparison.InvariantCultureIgnoreCase
            ));  // GetTheFirstOneOrReturnNull takes a Func<MyObject, bool>
    }
}

Как мне реплицировать лямбда-выражение с Moq?Я продолжаю получать исключение «Неподдерживаемое выражение».

Вот идея того, что я уже делаю:

[TestMethod]
public void GetByMyConstraintShouldReturnWithMyObject ()
{
    // Arrange
    const string MyConstraint = "Constraint";
    MyObject Expected = new MyObject { Constraint = MyConstraint };
    Mock<Repository<MyObject>> MockRepo = new Mock<Repository<MyObject>> ();
    MockRepo.Setup (x => x.GetTheFirstOneOrReturnNull (M => M.Constraint.Equals (MyConstraint, StringComparison.InvariantCultureIgnoreCase)))
            .Returns (Expected).Verifable ();
    MyService Service = new MyService (MockRepo.Object);

    // Act
    MyObject Result = Service.Get (MyConstraint);


    // Assert
    Assert.AreSame (Expected, Result);
    MockRepo.Verify ();

}

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

Это единственный вариант для инкапсуляции лямбдаВыражение внутри объекта и передать в хранилище и выполнить запрос?Я не хочу менять свой код только для своей среды тестирования, но я также не хочу тратить время на попытки подчинить эту вещь своей воле.

Ответы [ 3 ]

1 голос
/ 10 июня 2011

Я бы сказал, что ваша лучшая ставка - обновить Repository, чтобы он был похож на FindByConstraint метод, где все, что вы проходите, это Constraint, а сам репо делает FirstOrDefault(). Я думаю, что есть разумные конструктивные причины для этого, а также просто для того, чтобы упростить тестирование - поиск выполняется без учета регистра и с радостью вернет ноль, что можно увидеть как решения, которые должен принимать Repo, а не его клиенты. .

Я лично испытываю трудности при тестировании объекта, чтобы показать, что в моем дизайне есть изъян, и я думаю, что объекты, которые легко тестируются, - это то, к чему стоит стремиться.

1 голос
/ 10 июня 2011

Для этого не нужно много тестировать.Один правильный тест покажет, что код, делегирующий FirstOrDefault, работает, затем все последующие тесты действительно проверяют правильность логики в ограничении Func, которую можно выполнить, не передавая ее в Repository.

1 голос
/ 10 июня 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...