JamesFaix
JamesFaix

Reputation: 8665

How can I use an NUnit test case that is dependent on TestSetup method having run?

I am using NUnit 2 to write some unit tests for C#. My environment is Visual Studio 2015 Professional with Resharper installed.

The problem I am having is with some parameterized tests I try to create using TestCaseSourceAttribute. In simple cases I can create tests like this that will work fine:

[Test, TestCaseSource(nameof(MyTestCases))]
public void MyTest(string name) {
    Assert.IsFalse(String.IsNullOrEmpty(name));
}

private static IEnumerable<TestCaseData> MyTestCases {
    get {
        yield return new TestCaseData("test");
        yield return new TestCaseData("123");
    }
}

However, when I try to instantiate types that must be mapped from database entities or that check the database in their initialization process, the test is ignored by the test runner. For example:

[Test, TestCaseSource(nameof(MyTestCases))]
public void MyTest(MyMappedType instance) {
    Assert.IsTrue(instance.SomeProperty);
}

private static IEnumerable<TestCaseData> MyTestCases {
    get {
        yield return new TestCaseData(GetAnInstanceOfMyMappedType());
        yield return new TestCaseData(GetADifferentInstanceOfMyMappedType());
    }
}

The instantiation of MyMappedType will work fine if it is in the test body itself, but the test is ignored if any of the test cases instantiate it.

Can I get these tests to work in a parameterized way? Any documentation references regarding this?


Update:

The problem appears to be due to some code in the test case property being dependent on the class's TestSetup method already having run. Is there a way to make setup run before initializing each test case rather than after?

Upvotes: 1

Views: 1625

Answers (2)

Arg
Arg

Reputation: 1

Using a property of the C# compiler, we can find a solution to this problem. The procedure is as follows:

  1. Retrieve data in a static method
  2. The static method is placed before all other members of the class
  3. It is important to note that the source is completed only once per execution (this is one of the limitations of this method)
  4. Test case can use the previous produced data.

Upvotes: 0

Charlie
Charlie

Reputation: 13736

No, there is no way for your setup to be called before your tests are generated.

Additionally, although it's possible to instantiate objects in your TestCaseSource method, those objects will go out of scope as soon as the method returns unless saved somewhere, like in a static member. And, of course, that would not be a very good practice.

Rewrite your TestCaseSource to provide parameters, like ints and strings, that can be used to create the objects you need at run-time.

If you want to create those objects just once per fixture, use OneTimeSetUp rather than SetUp and use a parameterized fixture to save the parameters needed for creating them.

Upvotes: 2

Related Questions