Почему я не могу захватить ожидание FakeItEasy в переменной?

Я использую FakeItEasy для подделки некоторых вызовов Entity Framework, чтобы убедиться, что куча странных устаревших таблиц базы данных отображается правильно.

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

Если я сделаю это:

A.CallTo(() => db.Customers.Add(
    A<Customer>.That.Matches(
        c => c.Invoices.First().Address == EXPECTED_ADDRESS)
    )
)).MustHaveHappened();

код работает отлично. Я хочу упростить синтаксис, переместив ожидание в другое место, но когда я это сделаю:

var expected = A<Customer>.That.Matches(
    c => c.Invoices.First().Address == EXPECTED_ADDRESS)
);
A.CallTo(() => db.Customers.Add(expected)).MustHaveHappened();

тест неудачи. Что происходит внутри кода FakeItEasy, что означает, что выражение ожидания работает, когда оно встроено, но не может быть захвачено в переменной и повторно использовано позже?

3 ответов


ответ находится в документах по адресу всегда место игнорируется и что внутри A. CallTo:

на Ignored_) и That сопоставители должны быть помещены в выражение внутри A.CallTo звонок. Это связано с тем, что эти специальные методы ограничений не возвращают фактический объект сопоставления. Они говорят FakeItEasy, как сопоставить параметр с помощью специального события, которое запускается, затем вызывается метод ограничения. FakeItEasy только слушает события в контекст A.CallTo.

Я удивлен, что "тест терпит неудачу", хотя. Какую версию вы используете? Начиная с FIE 2.0.0, используя That как ты сделал должен выбросить исключение как

System.InvalidOperationException : A<T>.Ignored, A<T>._, and A<T>.That
can only be used in the context of a call specification with A.CallTo()

не прямой ответ на то, почему выражение ожидания работает встроенным, но не в переменной (я работаю над этим, скоро отредактирую ответ!)

, Я не фанат .That.Matches

матчи могут стать немного громоздкими, если их больше одного. Плюс MustHaveHappened вызов вызовет исключение, если любой из матчей не удается. Не оставив мне ни малейшего представления, где произошла неудача.

Я предпочитаю делать это:

Customer addedCustomer;
A.CallTo(() => a.Add(A<Customer>._))
    .Invokes(c => addedCustomer = c.GetArgument<Customer>(0));

//Individual Asserts on addedCustomer
Assert.AreEqual(EXPECTED_ADDRESS, addedCustomer.Invoices.First().Address);

ответ Блэр правильный. Я просто хочу предложить обходной путь:

// Local function, requires C# 7
Customer ExpectedCustomer() =>
    A<Customer>.That.Matches(
        c => c.Invoices.First().Address == EXPECTED_ADDRESS));

A.CallTo(() => db.Customers.Add(ExpectedCustomer())).MustHaveHappened();