MSTest v2: Exploring asserts

This post is part of the serie 'MSTest v2'. Be sure to check out the rest of the blog posts of the serie!

In the previous post, we created a simple test and run it. You write a test to assert your code behave as expected. This means, assertions are central to unit testing in any frameworks, and MSTest is no exception. MSTest provides a rich set of assertions. So, today we'll explore the Assert classes.

An assertion method is a method that takes paramters and ensure a condition is met. For instance, AreEqual takes 2 values and check they are equal. If an assertion fails, the method call does not return and an error is reported. The method throws an exception with a formatted message. If a test contains multiple assertions, any that follow the one that failed will not be executed.

[TestMethod]
public void Test()
{
    Assert.AreEqual(10, 5 + 5); // Success
    Assert.AreEqual(10, 1 + 2); // 10 ≠ 3 => Error.
    Assert.AreEqual(20, 1 + 2); // Not executed
}

Now, we can explore the different assert methods of the framework.

Assertion on a single value

The following assert methods validate a value meet a specific condition. I won't explain all of them because the usage is pretty clear.

  • Assert.AreEqual(object expected, object actual): Tests whether the specified values are equal. Different numeric types are treated as unequal even if the logical values are equal. 42L is not equal to 42.
  • Assert.AreNotEqual(object expected, object actual): Tests whether the specified values are unequal. Same as AreEqual for numeric values.
  • Assert.AreSame(object expected, object actual): Tests whether the specified objects both refer to the same object
  • Assert.AreNotSame(object expected, object actual): Tests whether the specified objects refer to different objects
  • Assert.IsTrue(bool condition): Tests whether the specified condition is true
  • Assert.IsFalse(bool condition): Tests whether the specified condition is false
  • Assert.IsNull(object value): Tests whether the specified object is null
  • Assert.IsNotNull(object value): Tests whether the specified object is non-null
  • Assert.IsInstanceOfType(object value, Type type): Tests whether the specified object is an instance of the expected type
  • Assert.IsNotInstanceOfType(object value, Type type): Tests whether the specified object is not an instance of the wrong type
  • StringAssert.Contains(string value, string substring): Tests whether the specified string contains the specified substring
  • StringAssert.StartsWith(string value, string substring): Tests whether the specified string begins with the specified substring
  • StringAssert.Matches(string value, Regex regex): Tests whether the specified string matches a regular expression
  • StringAssert.DoesNotMatch(string value, Regex regex): Tests whether the specified string does not match a regular expression

I'll only provide an example for AreEqual and AreSame because the difference is more subtile.

var expected = "a";
var actual = "a";

Assert.AreEqual(expected, actual);    // success
Assert.AreSame(expected, actual);     // fail

Assert.AreNotEqual(expected, actual); // fail
Assert.AreNotSame(expected, actual);  // success

Assert.AreEqual(42, 42);              // success
Assert.AreEqual(42, 42L);             // fail

Assertion on collections

  • CollectionAssert.AreEqual(ICollection expected, ICollection actual): Tests whether the specified collections have the same elements in the same order and quantity.
  • CollectionAssert.AreNotEqual(ICollection expected, ICollection actual): Tests whether the specified collections does not have the same elements or the elements are in a different order and quantity.
  • CollectionAssert.AreEquivalent(ICollection expected, ICollection actual): Tests whether two collections contain the same elements.
  • CollectionAssert.AreNotEquivalent(ICollection expected, ICollection actual): Tests whether two collections contain different elements.
  • CollectionAssert.AllItemsAreInstancesOfType(ICollection collection, Type expectedType): Tests whether all elements in the specified collection are instances of the expected type
  • CollectionAssert.AllItemsAreNotNull(ICollection collection): Tests whether all items in the specified collection are non-null
  • CollectionAssert.AllItemsAreUnique(ICollection collection): Tests whether all items in the specified collection are unique
  • CollectionAssert.Contains(ICollection collection, object element): Tests whether the specified collection contains the specified element
  • CollectionAssert.DoesNotContain(ICollection collection, object element): Tests whether the specified collection does not contain the specified element
  • CollectionAssert.IsSubsetOf(ICollection subset, ICollection superset): Tests whether one collection is a subset of another collection
  • CollectionAssert.IsNotSubsetOf(ICollection subset, ICollection superset): Tests whether one collection is not a subset of another collection

Here's an example to show the difference between AreEqual and AreEquivalent:

CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 1, 2 });    // success
CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 1, 2, 3 }); // fail
CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 2, 1 });    // fail

CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 1, 2 });    // success
CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 1, 2, 3 }); // fail
CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 2, 1 });    // success

Test an exception is thrown

  • Assert.ThrowsException<T>(Action action): Tests whether the code specified by delegate throws exact given exception of type T (and not of derived type)
  • Assert.ThrowsExceptionAsync<T>(Func<Task> action): Same as ThrowsException with async code
// success
Assert.ThrowsException<ArgumentNullException>(() => new Regex(null));

// fail
Assert.ThrowsException<ArgumentException>(() => new Regex(null));

Other asserts

The following assert methods are special. The first one Fail immediately change the status of the test to "error". This can be useful to write your own assert method. The second one, Inconclusive, indicates that the test could not be completed. In this case, the test is neither a success nor a failure.

  • Assert.Fail(string message)
  • Assert.Inconclusive(string message)

Here's an example of an inconclusive test

[TestMethod]
public void Sample8()
{
    if (DateTime.Now.Hour != 12)
        Assert.Inconclusive("Must be executed at noon");

    // actual tests...
}

In the test explorer, inconclusive tests are grouped into "Skipped Tests":

Conclusion

MSTest v2 comes with more than 30 assert methods. This should helps you writting your tests. In a future blog post, we'll see how to extend the list of assert methods with your own methods.

Leave a reply