HowTo – NUnit – Assertions

Source Code

All source code can be found on GitHub here.

My cheat sheet for NUnit can be found here.

This is part of my HowTo in .NET seriies. An overview can be seen here,

Intro

NUnit is a unit test framework for .net; it is very mature and contains lots of features when compared to XUnit.

This post is part of a 3 part post on NUnit:

  1. NUnit Features
  2. Assertions
  3. Fluent Assertions

This post covers the Assertions which are provided and are used to conditionally pass or fail a unit test.

Most of these are self explanatory so I will keep my words to a minimum, highlighting only the main or more obscure points.

The examples given are the simplest self explanatory way to define a pass using the assertion.

Equality

Equality Assertions allow passing and failing of a test by comparing two objects or primitive types for equality; there are many overloads allowing passing in any value or reference type.

Assert.AreEqual (true, true);
Assert.AreNotEqual (true, false);

Identity

Identity Assertions provide the ability to pass or fail a test by comparing two objects for identity; i.e are they the same object instance or memory reference.

The following examples also provide the ‘Contains’ function which allows determination that an element is found within a collection.

Assert.AreSame (string.Empty, string.Empty);
Assert.AreNotSame (new object (), new object ());
Assert.Contains (string.Empty, new List<object> (){string.Empty});

Condition

Condition Assertions provide a mixture of tests from checking a boolean is either false or true, a reference type is or is not null and collection is or is not empty. Empty can be used on any element implementing IEnumerable including String which is an array of chars.

Assert.IsTrue (true);
Assert.IsFalse (false);
Assert.IsNull (null);
Assert.IsNaN (Double.NaN);
Assert.IsEmpty (new List<object> ());
Assert.IsEmpty (new List<object> ());
Assert.IsNotEmpty (new List<object> (){1});
Assert.IsNotEmpty ("Foo");

Comparison

Comparison Assertions provide tests for comparing types which are numbers. The first parameter is the test object and the second parameter is the comparative object.

Assert.Greater (Decimal.MaxValue, Decimal.MinValue);
Assert.GreaterOrEqual (Decimal.MinValue, Decimal.MinValue);
Assert.Less (Decimal.MinValue, Decimal.MaxValue);
Assert.LessOrEqual (Decimal.MinValue, Decimal.MinValue);

The type assertions provide tests or determining an objects or types type.

Assignable determination uses Type.IsAssignableFrom() Method and determines is a type can be cast from another. More information can be seen here http://msdn.microsoft.com/en-gb/library/system.type.isassignablefrom.aspx.

Generic and non Generic implementations are also catered for:


Assert.IsInstanceOf<decimal> (decimal.MinValue);
Assert.IsNotInstanceOf<int> (decimal.MinValue);

Assert.IsNotAssignableFrom (typeof(List<Type>), string.Empty);
Assert.IsAssignableFrom (typeof(List<decimal>), new List<decimal> ());

Assert.IsNotAssignableFrom<List<Type>> (string.Empty);
Assert.IsAssignableFrom<List<decimal>> (new List<decimal> ());

Exceptions

Exception Assertions allow testing of exceptions being thrown; generic and non generic implementations are catered for.

Throws requires the exception type to be thrown explicitly.
Catch allows the exact exception type or any derived exception of that type.

The functions all take a delegate which should be used to call the method to be tested. If the method is called without the delegate the method will be called outside of the scope of the assert and outside of the scope of the test; the exception will fail the test despite being the required result!


Assert.Throws (typeof(ArgumentNullException), () => { throw new ArgumentNullException (); } );
Assert.Throws<ArgumentNullException> (() => { throw new ArgumentNullException (); } );

Assert.DoesNotThrow (() => { });

Assert.Catch (typeof(Exception), () => { throw new ArgumentNullException (); } );
Assert.Catch<Exception> (() => { hrow new ArgumentNullException (); });

Strings

A number of String assertions. The first parameter is the string under test and the second is the expected result. The test is case sensitive unless the method name states otherwise. IsMatch provides regular expression test.

StringAssert.Contains ("Foo", "MooFooMoo");
StringAssert.StartsWith ("Foo", "FooMoo");
StringAssert.EndsWith ("Moo", "FooMoo");
StringAssert.AreEqualIgnoringCase ("FOO", "foo");
StringAssert.IsMatch ("[0-9]", "1");

Assertions for collections, the method names and examples are self explanatory.

AreEqual requires each element to be the same in equality and the same position, AreEquivalent allows the elements to be in any position in the collection.

SubSet allows checking that all elements in a collection are found in another without caring if there are more elements to be found.

An example of overriding the ICompare for ordering is also provided.


// All Items Are....
CollectionAssert.AllItemsAreInstancesOfType (new List<decimal> (){ 0m }, typeof(decimal));
CollectionAssert.AllItemsAreNotNull (new List<decimal> (){ 0m });
CollectionAssert.AllItemsAreUnique (new List<decimal> (){ 0m, 1m });

// Equal and Equivalent
CollectionAssert.AreEqual (new List<decimal> (){ 0m }, new List<decimal> (){ 0m });
CollectionAssert.AreEquivalent (new List<decimal> (){ 0m, 1m }, new List<decimal> (){ 1m, 0m }); // Same as AreEqual though order does not mater
CollectionAssert.AreNotEqual (new List<decimal> (){ 0m }, new List<decimal> (){ 1m });
CollectionAssert.AreNotEquivalent (new List<decimal> (){ 0m, 1m }, new List<decimal> (){ 1m, 2m });  // Same as AreNotEqual though order does not matter

// Contains
CollectionAssert.Contains (new List<decimal> (){ 0m, 1m }, 1m);
CollectionAssert.DoesNotContain (new List<decimal> (){ 0m, 1m }, 2m);

//Subset
CollectionAssert.IsSubsetOf (new List<decimal> (){ 1m }, new List<decimal> (){ 0m, 1m }); // {1} is considered a SubSet of {1,2}
CollectionAssert.IsNotSubsetOf (new List<decimal> (){ 1m, 2m }, new List<decimal> (){ 0m, 1m });

//Empty
CollectionAssert.IsEmpty (new List<decimal> (){ });
CollectionAssert.IsNotEmpty (new List<decimal> (){ 1m });

// Ordered
CollectionAssert.IsOrdered (new List<decimal> (){ 1m, 2m, 3m });
CollectionAssert.IsOrdered (new List<string> (){ "a", "A", "b"}, StringComparer.CurrentCultureIgnoreCase);
CollectionAssert.IsOrdered (new List<int> (){ 3,2,1}, new ReverseComparer()); // Only supports ICompare and not ICompare<T> as of version 2.6

// IComparer

public class ReverseComparer : IComparer
	{
		public int Compare (object a, object b)
		{
			return ((int)b).CompareTo((int)a);
		}
	}

FileAssert

FileAssert provides ways to compare file contents or streams. There are overrides for providing a file name or stream. The tests are comparing the contents and not the file paths.


//  File Assert: various ways to compare a stream or file.
FileAssert.AreEqual (new MemoryStream (), new MemoryStream ());
FileAssert.AreEqual (new FileInfo ("MyFile.txt"), new FileInfo ("MyFile.txt"));
FileAssert.AreEqual ("MyFile.txt", "MyFile.txt");

FileAssert.AreNotEqual (new FileInfo ("MyFile.txt"), new FileInfo ("MyFile2.txt"));
FileAssert.AreNotEqual ("MyFile.txt", "MyFile2.txt");
FileAssert.AreNotEqual (new FileStream ("MyFile.txt", FileMode.Open), new FileStream ("MyFile2.txt", FileMode.Open));

Utilities allow immediate stopping of the unit tests with declaration of the test result:

Assert.Pass ();
Assert.Fail ();
Assert.Ignore ();
Assert.Inconclusive ();

Providing custom fail messages

Custom fail messages can be provided for all of the above assertions. The last parameter is always the custom fail message. These should not always be needed if you name your test methods as descriptively. If your assertions are checking completely different checks on your SUT ( subject under test ) such that custom fail messages are required; perhaps you should think of splitting the test up into multiple tests.

Assert.IsTrue(true, "A failed message here"); // also object[] params can be defined
Advertisements

One thought on “HowTo – NUnit – Assertions

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