Why can't I capture a FakeItEasy expectation in a variable?

自作多情 提交于 2019-12-05 07:16:08

The answer is in the docs at Always place Ignored and That inside A.CallTo:

The Ignored (and _) and That matchers must be placed within the expression inside the A.CallTo call. This is because these special constraint methods do not return an actual matcher object. They tell FakeItEasy how to match the parameter via a special event that's fired then the constraint method is invoked. FakeItEasy only listens to the events in the context of an A.CallTo.

I'm surprised the "test fails", though. What version are you using? As of FIE 2.0.0, using That as you did should throw an exception like

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()

Not a direct answer for why the expectation expression works inline, but not in a variable (I'm working on that, will edit answer shortly!)

However, I'm not a fan of .That.Matches

The matches can get a bit unwieldy if there's more than one. Plus the MustHaveHappened call will throw an exception if any of the matches fail. Leaving me no idea where the failure happened.

I prefer to do this:

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);

Blair's answer is correct. I just want to suggest a workaround:

// 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();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!