Search code examples
c#unit-testingapproval-tests

Using an abstract base test class with approval tests


Assuming I had a very good reason to want to do the tests below, how could I setup approval tests to name the .approved files UnitTest1.Test1.approved instead of BaseTest.Test1.approved? Thanks

public abstract class BaseTest
{
    [TestMethod]
    public void Test1()
    {
        Approvals.Verify(1);
    }

    [TestMethod]
    public void Test2()
    {
        Approvals.Verify(2);
    }
}

[TestClass]
public class UnitTest1 : BaseTest
{
    public UnitTest1()
    {
        // some initialization
    }
}

[TestClass]
public class UnitTest2 : BaseTest
{
    public UnitTest2()
    {
        // some initialization
    }
}

=== UPDATE ===

Based on Llewellyn's suggestion I added the following code to the ctor of the base class:

public BaseTest()
{
    NamerFactory.AdditionalInformation = GetType().Name;
}

Works as expected, I get separate .approved files for each test.


Solution

  • That is an interesting assumption. I am assuming you would want both UnitTest1.Test1.approved & UnitTest2.Test1.approved

    The short answer is not exactly, but there are a few work arounds.

    WorkAround #1 - NamerFactory (BaseTest.Test1.UnitTest1.approved.txt)

    You could rewrite the test to be

    [TestMethod]
    public void Test2()
    {
        NamerFactory.AdditionalInformation = this.GetType().Name;
        Approvals.Verify(2);
    }
    

    btw: this is better with the using statement if you are using the nightly builds from myget https://www.myget.org/gallery/approvaltests

    using (NamerFactory.AsEnvironmentSpecificTest(() => this.GetType().Name))
    {
        Approvals.Verify(1);
    }
    

    WorkAround #2 - Call from OutsideClass (UnitTest1.Test1.approved.txt)

    You can extract the bulk of the method and then Call it from outside test. There is a good chance you might want all the functionality of a method, but still want the test to be in the extending class. The Approvals call does not need to be in the topmost test method. For example:

    public abstract class BaseTest
    {
        public void Verify1()
        {
            // other code to do stuff
            Approvals.Verify(1);
        }
    
    }
    
    [TestClass]
    public class UnitTest1 : BaseTest
    {
        public UnitTest1()
        {
            // some initialization
        }
        [TestMethod]
        public void Test1()
        {
            Verify1();
        }
    }