Aspiring Craftsman

pursuing well-crafted software

Expected Objects Custom Comparisons

ExpectedObjects is a testing library I developed a few years ago to facilitate using the Expected Objects pattern within my specifications to avoid obscure tests.  You can find the original introduction to the library here.

As of version 1.1.0, the ExpectedObjects library has been updated to include a feature called Custom Comparisons.  The standard behavior of the library is to traverse a strategy chain (which is itself configurable) to determine which comparison strategy is to be used for each type of object encountered within the object graph.  The Custom Comparisons feature allows you to override this behavior for specific properties.

For example, let’s say we’re writing a end-to-end test which validates a Receipt class as follows:

public class Receipt

    public string Name { get; set; }
    public DateTime TransactionDate { get; set; }
    public string VerificationCode { get; set; }


Given the following class, the VerificationCode property would probably not be a value you could anticipate.  In such a case, while you can’t verify that the property has a specific value, you may care that it at least has some value.  This is where the Custom Comparisons feature can help.  We can verify that the actual Receipt received matches the expected receipt structure using the following expected object configuration:

var expected = new
	Name = "John Doe",
	DateTime = DateTime.Today,
	VerificationCode = Expect.NotNull()

var actual = new Receipt
	Name = "John Doe",
	DateTime = DateTime.Today,
	VerificationCode = "ABC123"


In the event that the VerificationCode property is null, the library will raise an exception with the following message:

For Receipt.VerificationCode, expected a non-null value but found [null].

The ExpectedObjects library currently provides a static Expect class which  includes convenience methods to check for null, not null, and an Any comparison for checking that an object is of a specific type (e.g. Expect.Any()).  To supply your own comparisons, simply implement the IComparsion interface which defines the custom comparison and the text to include within any exception messages raised (e.g. “For SomeType.SomeProperty, expected [_text you supply here_] but found “42”).