Hi,
The reason for that behavior is Isolator default sequencing behavior. This behavior makes a list of sequential
WhenCalled's return their result after each other. This behavior is applied on any method recording unless used
WithExactArguments.
Example for simple sequence:
ClassToFake fake = Isolate.Fake.Instance<ClassToFake>();
Isolate.WhenCalled(() => fake.GetNum()).WillReturn(1);
Isolate.WhenCalled(() => fake.GetNum()).WillReturn(2);
Assert.That(fake.GetNum(), Is.EqualTo(1));
Assert.That(fake.GetNum(), Is.EqualTo(2));
Example for sequence with respect to arguments:
ClassToFake fake = Isolate.Fake.Instance<ClassToFake>();
Isolate.WhenCalled(() => fake.Translate("One")).WithExactArguments().WillReturn(1);
Isolate.WhenCalled(() => fake.Translate("Two")).WithExactArguments().WillReturn(2);
Assert.That(fake.Translate("Two"), Is.EqualTo(2));
Assert.That(fake.Translate("One"), Is.EqualTo(1));
In the original posted case there's no usage of
WithExactArguments. There's still a problem since the argument type if
Func<string, bool> which doesn't implement equality members. There are two possible workarounds -
Sequence
In this case we ignore the arguments and make the test dependent on a specific calls order by the production code. The advantage of this is that it's very simple, but it is a little fragile.
Wrapper
Another workaround is to create a wrapper method which receives
string argument and its body performs the "real" filtering. In the production replace the calls to
SingleOrDefault with the new method in the test replace the faking behavior with the new method.
Please let me know if it helps.
Regards,
Elisha,
Typemock Support