Почему я не могу захватить ожидание 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();