Using NHamcrest with NUnit or XUnit

NHamcrest is supported out of the box with MbUnit, but there’s nothing stopping you using it with any other framework.

You just need to write the shim code, i.e. Assert.That.

For example, with NUnit it would look something like this:

public static void That<T>(T actual, IMatcher<T> matcher, string message, params object[] args)
{
	if (matcher.Matches(actual))
		return;
	
	var writer = new TextMessageWriter(message, args);

	WriteExpected(matcher, writer);

	WriteActual(actual, matcher, writer);

	throw new AssertionException(writer.ToString());
}

private static void WriteExpected(ISelfDescribing matcher, TextWriter writer)
{
	writer.Write(TextMessageWriter.Pfx_Expected);
	var description = new StringDescription();
	matcher.DescribeTo(description);
	writer.Write(description.ToString());
	writer.WriteLine();
}

private static void WriteActual<T>(T actual, IMatcher<T> matcher, TextWriter writer)
{
	writer.Write("  But ");
	var mismatchDescription = new StringDescription();
	matcher.DescribeMismatch(actual, mismatchDescription);
	writer.Write(mismatchDescription.ToString());
	writer.WriteLine();
}

For XUnit:

public static void That<T>(T actual, IMatcher<T> matcher)
{
	if (matcher.Matches(actual))
		return;

	var description = new StringDescription();
	matcher.DescribeTo(description);

	var mismatchDescription = new StringDescription();
	matcher.DescribeMismatch(actual, mismatchDescription);

	throw new MatchException(description.ToString(), mismatchDescription.ToString(), null);
}

public class MatchException : AssertActualExpectedException
{
	public MatchException(object expected, object actual, string userMessage) : base(expected, actual, userMessage)
	{
	}
}

And, for completeness, here’s the MbUnit version:

        public static void That<T>(T item, IMatcher<T> matcher, string messageFormat, params object[] messageArgs)
        {
            AssertionHelper.Verify(() =>
            {
                if (matcher.Matches(item))
                    return null;

                var description = new StringDescription();
                var mismatchDescription = new StringDescription();

                matcher.DescribeTo(description);
                matcher.DescribeMismatch(item, mismatchDescription);

                return new AssertionFailureBuilder("Expected " + description)
                    .SetMessage(messageFormat, messageArgs)
                    .AddLabeledValue("Expected", description.ToString())
                    .AddLabeledValue("But", mismatchDescription.ToString())
                    .ToAssertionFailure();
            });           
        }

4 thoughts on “Using NHamcrest with NUnit or XUnit

  1. Graham Hay May 10, 2012 / 2:45 pm

    To include the shims? I’d rather not couple it to any specific test frameworks.

    I could create an NHamcrest.[NUnit|XUnit] package, but it seems like overkill for one class.

  2. Søren Bjerregaard Vrist May 22, 2012 / 8:31 pm

    Yearh, you are probably right.

    Regarding the shims I’m having some troubles with the
    Assert.That(t, Is.InstanceOf()) if t : S and T : S as the type of Assert.That(T,IMatcher) wont allow the mismatches.

    I see that NUnit does this with something along the lines of Is.InstanceOf : object

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s