When setting expectations on object values, it's quite useful to evaluate the expected values in a lazy way, so that the test code has a chance to set the value.
i.e. consider the case where I'm setting an expectation on a view interface that will check that an argument passed-in matches a value existing on the correponding presenter, which is what's under test:
Expect.Once.On(view).
Method("SetDatabaseFilename").With(DatabaseFilename);
Expect.Once.On(view).
Method("SetDatabase").With(new LazyEqualsToMatcher(delegate() { return presenter.Database; }));
presenter.DatabaseFileChanged(Path.GetFullPath(DatabaseFilename));
Note that it's the presenter action DatabaseFileChanged the one that actually sets the presenter.Database value that we need in order to verify the expectation on the view. Without a lazy evaluation of that property at the time the method is invoked on the view, we have no way of actually setting the expectation. If we had used:
Expect.Once.On(view).
Method("SetDatabase").With(presenter.Database);
The database would have been null at that point, and the expectation would be wrong.
The LazyEqualsToMatcher is pretty simple:
public delegate object LazyValueHandler();
public class LazyEqualsToMatcher : Matcher
{
LazyValueHandler valueHandler;
public LazyEqualsToMatcher(LazyValueHandler valueHandler)
{
this.valueHandler = valueHandler;
}
public override void DescribeTo(TextWriter writer)
{
Is.EqualTo(valueHandler()).DescribeTo(writer);
}
public override bool Matches(object o)
{
return Is.EqualTo(valueHandler()).Matches(o);
}
}
It just wraps the Is.EqualsTo matcher but evaluates the property at matching time instead of construction time.
Thanks.