DEV Community

Cover image for How to create custom assertions in C# with MSTest
Cesar Aguirre
Cesar Aguirre

Posted on • Originally published at canro91.github.io

How to create custom assertions in C# with MSTest

I originally posted an extended version of this post on my blog a couple of weeks ago. It's part of a series I've been publishing, called "Unit Testing 101"

Last time, we went through some best practices to write better assertions on our tests. This time, let's focus on how to use custom assertions in our tests.

Use custom assertions to encapsulate multiple assertions on a single method and to express assertions in the same language as the domain model. Write custom assertions with local methods or extension methods on the result object of the tested method or on the fakes objects.

We can either create custom assertions on top of MSTest Assert class. And, our own Verify() methods on Moq mocks.

Custom MSTest Assert methods

Let's write a custom assertion method with MSTest.

To write custom assertions with MSTest, write an extension method on top of the Assert class. Then, compare the expected and actual parameters and throw an AssertFailedException if the comparison fails.

Here, we're creating a StringIsEmpty() method.

internal static class CustomAssert
{
    public static void StringIsEmpty(this Assert assert, string actual)
    {
        if (string.IsNullOrEmpty(actual))
            return;

        throw new AssertFailedException($"Expect empty string but was {actual}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Then, we can use StringIsEmpty() with the That property. Like this,

Assert.That.StringIsEmpty("");
Enter fullscreen mode Exit fullscreen mode

With this new assertion method, we can refactor one of our tests for Stringie, a (fictional) library to manipulate strings. We used Stringie to learn 4 common mistakes when writing tests and 4 test naming conventions.

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Stringie.UnitTests
{
    [TestClass]
    public class RemoveTests
    {
        [TestMethod]
        public void Remove_NoParameters_ReturnsEmpty()
        {
            string str = "Hello, world!";

            string transformed = str.Remove();

            Assert.That.StringIsEmpty(transformed);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

With our custom StringIsEmpty() method, our test is more readable. And, we wrote the tests in the same terms as our domain language.

Even better, since our StringIsEmpty() method deals with strings, we can use the StringAssert class as parameter in our custom method and rename it to IsEmpty().

Voilà! That's how to write custom assertions with MSTest. With custom assertions we have our tests written in the same terms as our domain model.

Remember, you can simply write private methods grouping your regular assertions and share them in a base test class. Or write extensions methods on the output of the method being tested. That would make your test even easier to read.

For more best practices on unit testing, check my posts Unit Testing Best Practices and how to write better assertions.

If you're new to unit testing or want to learn more, stay tune to my "Unit Testing 101" series on my blog.

Happy testing!

Discussion (0)