C# – Correct Way To Run Test Set Up with Nunit TestCaseSource

cnunittestcasesourceunit testing

I am trying to run multiple tests using TestCaseSource in NUnit. But I am struggling to get the [SetUp] to run when I want it.

At the moment it works how I want it to but it doesnt feel "right". So the following is the main test case code (simplified):

public class ImportTestCases
{

    ImportTestCases()
    {
        TestData.RunTestSetup();
    }

    public static IEnumerable TestCases
    {
        get
        {
            //run the funciton under test...
            var results = RunFunctionSubjectToTest(TestData.ImportantVar);

            //get multiple results...
            var allProperties =new TestCaseData(o).Returns(true)
                ExpandNestedProperties(results.AllProperties)
                    .ToList()
                    .ConvertAll(o => new TestCaseData(o).Returns(true));

            return allProperties;
        }
    }


}


[TestFixture]
public class ImportTests
{

    [TestFixtureSetUp]
    public void ImporTestSetup()
    {
        TestData.RunTestSetup();
    }

    [Test, TestCaseSource(typeof(ImportTestCases), nameof(ImportTestCases.TestCases))]
    public bool PropertyTest(UnitTestHelper.PropInfo info)
    {
        return info.DoTheyMatch;
    }

}

The trouble here is that [SetUp] does not run before ImportTestCases "TestCases"
property "get" is ran. The Constructor of "ImportTestCases" is not ran either. So in order to ensure "RunTestSetup" is ran before ImportVar is referenced I have to do the following:

public static class TestData
{
    private static bool HasSetUpRan = false;
    private static int _importantVar;
    public static int ImportantVar
    {
        get
        {
            if(!HasSetUpRan)
            {
                RunTestSetup();
            }
            return _importantVar;
        }
    }        
    public static void RunTestSetup()
    {
        if (HasSetUpRan)
        {
            return;
        }
        ///do set up
        //e.g. _importantVar = GenerateId();
        //end
        HasSetUpRan= true;
    }

}

As you can see this ensures that Set up has ran before the variable is returned. Sadly this is the only way I have managed to get it to work so far. Which as I say feels "wrong" and over complicated. Perhaps I am overusing testCases here? or I should use some kind of paramatised testcase (is that possible?).

I have tried to simplify the code above so apologies if it simply doesnt make sense what I am trying to test.

The main point is is there a [Setup] that runs before TestCaseSources are created?

Best Answer

The main point is that test cases will be located at the time the tests are loaded. So the routine with [TestFixtureSetUp] attribute will be executed after the "TestCases" property is called. However you could execute some set-up routine within the static constructor. But in order to call it first you need to put your test data in the same class:

[TestFixture]
public class ImportTests
{
    static ImportTests() 
    {
        //Step 1 
        //run your set-up routine
    }

    //Step 3
    [Test, TestCaseSource(nameof(ImportTests.TestCases))]
    public bool PropertyTest(string s) => string.IsNullOrEmpty(s);

    //Step 2
    public static IEnumerable TestCases => new[] {new TestCaseData("").Returns(true)};
}
Related Topic