Bradley Braithwaite
1 import {
2 Learning,
3 JavaScript,
4 AngularJS
5 } from 'Brad on Code.com'
6 |
Check out my online course: AngularJS Unit Testing in-depth with ngMock.

Extending MSTest methods

I extended MSTest default methods so that I could add new features.

on
on Aesthetics, MSTest, TDD

I recently wrote a blog post about adding an Assert.Throws implementation for MSTest. This post goes into more detail of how I went about making MSTest extendible.

The basic premise of the first post was to add the Throws() method to MSTest. The implementation could be used as follows.

[TestMethod]
public void AddWithNegativeNumberThrowsExceptionExpectedMessage()
{
    // Arrange
    StringCalculator sc = new StringCalculator();
 
    // Act => Assert
    ExceptionAssert.Throws(() => sc.Add("-1"), "you cannot supply negative numbers.");
}

Regular MSTest users would appreciate the easier way of asserting an exception in a more readable manner, but they would also notice the need to type out ExceptionAssert.Throws() rather than Assert.Throws() as per the many other test methods of the framework e.g. Assert.AreEqual(), Assert.IsNull() and so on.

My initial plan was just to add the Throws() method as an extension method. Unfortunately the Microsoft.VisualStudio.TestTools.UnitTesting.Assert class is static, which put an end to that idea! This would mean I would have to create an extendible wrapper to sit on top of the MSTest Assert class. I want to retain all of the features of this class as well as being able to add my own extension methods.

The main element that acts as the central point for this to work is the following interface:

public interface IAssertion
{

}

We simply pass this around where we want to extend methods. The next step is to create the class we are going use for the instance of our Assert wrapper.

public class Assertion : IAssertion
{

}

I then moved over to the ExceptionAssert class and added an overloaded Throws() method that accepts an IAssertion parameter to make the method an extension method. This would read as:

public static void Throws<T>(this IAssertion assertion, Action task) where T : Exception
{
     Throws<T>(task, null, ExceptionMessageCompareOptions.None);
}

Now all we have to do, is add a variable in our class called Assert: public static readonly IAssertion Assert = new Assertion(); In our tests we can use the same Assert. notation however it will be using the instance of Assertion. I took this further in the class library I created and included this in a base test class. This makes things very simple, since you can just download the package from Nuget, inhert from BaseTest in your current test class, and things just work. Here is an example:

[TestClass]
public class ThrowsTests : BaseTest
{
    [TestMethod]
    public void MethodThrowsException()
    {
        Assert.Throws(() => { throw new Exception(); });
    }
}

###What about the default MSTest methods?

I created a wrapper class called MsTestAssertions which had the exact same method signatures from the real Assert class in MSTest. The difference is that we pass an IAssertion as the first parameter to make the method work as an extension. Each method calls the real implementation:

public static void AreEqual(this IAssertion assertion, System.Double expected, System.Double actual, System.Double delta, System.String message)
{
    Assert.AreEqual(expected, actual, delta, message);
}

Get the Source Code

Source code for MSTestExtensions.

####Download from Nuget

PM> Install-Package MSTestExtensions

See the Nuget project page for MSTestExtensions.

SHARE
Don't miss out on the free technical content:

Subscribe to Updates

CONNECT WITH BRADLEY

Bradley Braithwaite Software Blog Bradley Braithwaite is a software engineer who works for search engine start-ups. He is a published author at pluralsight.com. He writes about software development practices, JavaScript, AngularJS and Node.js via his website . Find out more about Brad. Find him via:
You might also like:
mean stack tutorial AngularJS Testing - Unit Testing Tutorials