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?
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)};
}