Argument constraints
When configuring and asserting calls in FakeItEasy, the arguments of the call can be constrained so that only calls to the configured method where the arguments matches the constraint are selected.
Matching values exactly
Assume the following interface exists:
Then the arguments to Bar can be constrained used to limit call matching:
Then FakeItEasy will look only for calls made with the arguments
"hello"
and 17
- no other calls will match the rule.
When checking for argument equality, FakeItEasy uses
object.Equals
. If the type to be checked does not provide an
adequate Equals
method, you may have to use the That.Matches
method described in Custom Matching. Be
particularly careful of types whose Equals
methods perform reference
equality rather than value equality. In that case, the objects have to
be the same object in order to match, and this sometimes produces
unexpected results. When in doubt, verify the type's Equals
behaviour manually.
Other matchers
Ignoring arguments
Suppose the value of the integer in the Bar
call wasn't important,
but the string was. Then the following constraint could be used:
Then any call will match, so long as the string value was
"hello"
. The Ignored
property can be used on any type.
An underscore (_
) can be used as a shorthand for Ignored
as well:
More convenience matchers
If more complicated constraints are needed, the That
method can be
used. There are a few built-in matchers:
Matcher | Tests for |
---|---|
IsNull() | null |
IsEqualTo(other) | object equality using object.Equals |
IsSameAs(other) | object identity - like object.ReferenceEquals |
IsInstanceOf(type) | an argument that can be assigned to a variable of type type |
Contains(string) | substring match |
StartsWith(string) | substring at beginning of string |
EndsWith(string) | substring at end of string |
IsNullOrEmpty() | null or "" |
IsEmpty() | empty enumerable |
Contains(item) | item's presence in an enumerable |
IsSameSequenceAs(enumerable) | sequence equality, like System.Linq.Enumerable.SequenceEqual |
Not | inverts the sense of the matcher |
Custom matching
If none of the canned matchers are sufficient, you can provide a
predicate to perform custom matching using That.Matches
. Like in
this rather contrived example:
FakeItEasy will evaluate the predicate against any supplied
argument. The predicate can be supplied as an Expression<Func<T,
bool>>
or as a Func<T, bool>
. FakeItEasy can generate a description
of the matcher when an Expression
is supplied (although you may
supply your own as well), but you must supply a description when using
a Func
.
For another example of using That.Matches
, see Jonathan Channon's
Comparing object instances with FakeItEasy.
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
.
So, tempting as it might be to save one of the constraints away in a handy variable, don't do it.
Out parameters
The incoming argument value of out parameters is ignored when matching calls. The incoming value of an out parameter can't be seen by the method body anyhow, so there's no advantage to constraining by it.
For example, this test passes:
string configurationValue = "lollipop";
A.CallTo(()=>aFakeDictionary.TryGetValue(theKey, out configurationValue))
.Returns(true);
string fetchedValue = "licorice";
var success = aFakeDictionary.TryGetValue(theKey, out fetchedValue);
Assert.That(success, Is.True);
See
Implicitly Assigning out Parameter Values
to learn how the initial configurationValue
is used in this case.
Overriding argument matchers
Sometimes individually constraining arguments isn't sufficient. In such a case, other methods may be used to determine which calls match the fake's configuration.
WithAnyArguments
ensures that no argument constraints will be applied when matching calls:
The example above will match any call to foo.Bar
, regardless of the arguments. The
Ignored
property performs the same task, and is more flexible, but
some people prefer the look of WithAnyArguments
.
WhenArgumentsMatch
accepts a predicate that operates on the entire
collection of call arguments. For example, to have a Fake throw an
exception when a call is made to Bar
where the first arguments is a
string representation of the second, use