Do you use TestInitialize or the test class constructor to prepare each test? and why?

Viewed 56175

This question regards unit testing in Visual Studio using MSTest (this is important, because of MSTest's execution order). Both the method marked [TestInitialize] and the test class constructor will run before each test method.

So, the question is, what do you tend to do in each of these areas? Do you avoid performing certain activities in either? What is your reason: style, technical, superstition?

10 Answers

The main advantage of using either TestInitialize() or ClassInitialize() rather than the test class instance or static constructors is its explicit nature. It clearly communicates that you are doing some setup prior to your tests. Doing this consistently should improve maintainability in the long run.

I prefer to use the [TestInitialize] method to perform instantiation of the object being tested and it's parameters. I only perform work in the constructor if it is necessary to instantiate a testing base class (which is usually where I create or refresh repositories, etc). This helps me keep the test framework code and test code separate logically and physically.

With async there is another reason (that did not exist when this question was asked) for [TestInitialize]. It allows you to do async operations to setup (eg. load a file) which is not possible in the constructor:

        private string approver;        

        [TestInitialize]
        public async Task Initialize()
        {
            approver = await File.ReadAllTextAsync("approver.json");
        }

The object you test doesn't need to be instantiated in the [TestInitialize] method. You can test the constructor of your object in a test method [Test].

Object in the [TestInitialize] can be to setup your persistance storage or to prepare value that the object tested will used in the tests.

I hope somebody still needs that. This is my solution, how to unit test class constructor. I am unit testing class service and throwing an exception if debuggingService is null.

DebuggingStepTests class constructor

private readonly IDebuggingService debuggingService;

public string StepName { get; set; }

public DebuggingStep(IDebuggingService _debuggingService)
{
    _log.Starting();
    StepName = "DebuggingStep";

    debuggingService = _debuggingService 
        ?? throw new ArgumentException("DebuggingStep init failure due to => IDebuggingService null");
}

UnitTests looks like this

    [Fact]
public void TestDebuggingStepConstructorWhen_InitServiceIsNull_ResultArgumentException() 
{
    //Arrange
    var arrange = new Action(() => 
    {
        new DebuggingStep(null);
    });

    //Act

    //Arrange
    Assert.Throws<ArgumentException>(arrange);
}

And actual result: enter image description here

Hope this will be helpful for somebody

Related