0

Abstract Context

I have a static stateful class (constraint: that I cannot change) that would like to cover 100%. It is a static class with a static state field. I'd like to test different inputs to a static method in the scenario where state is not already "set". This object does not have a publicly accessible mechanism for altering the piece of state of interest to the test.

Yes, I recognize this is a very good example of static-ness making testing painful.

My question here is to see how clever I can be without refactoring the unit under test.

I have not been able to find a framework way to accomplish this; I am aware that I could spin up a custom app domain for each test to get additional "copies" of my static object, but would like to avoid the heavy overhead (especially if I would be duplicating something the framework can accomplish).

Concrete Example

Consider the following class

public class Class1 { private static string _state; public static string DoStaticStateThing(string thing) { if(_state == null) { _state = thing; } return _state; } } 

and the following test fixture(s)

using NUnit.Framework; [TestFixtureSource(nameof(SourceEnumeration))] public class Class1Tests { private string _testInput; static object[] SourceEnumeration = { new object[] { "foo" }, new object[] { "bar" } }; public Class1Tests(string input) { _testInput = input; } [Test] public void TestStatefulThing() { string result = Class1.DoStaticThing(_testInput); Assert.AreEqual(_testInput, result); } } 

This results in the following test results

1 test passes, 1 test fails due to state; intuitively, I expected both to pass.

I was expecting both tests to start from the same state, where _thing is null, but this observation makes it clear that the object I am testing is surviving in memory between test executions.

I've poked around the documentation, found an interesting looking commit calling out MultipleDomainTestRunner that appears to no longer exist, and tried using the /domain=Multiple flag, all with no luck.

My Question

Can I alter the Class1Tests TestFixture in some way to accomplish what I want: each test executing over the same "starting state" of a stateful object?

1 Answer 1

1

NUnit provides no way to do this. When running using the console runner (nunit3-console.exe) all the tests in a particular assembly run in the same AppDomain. The MultipleDomainTestRunner you found is used when NUnit wants to run each assembly in its own AppDomain within the same process and so has no bearing on what you want to do.

Given that you can't change the class you are testing, running each test method within it's own AppDomain seems like a good solution. You would have to provide the infrastructure for creating the AppDomain yourself and you would need to make sure that you were not referencing the class itself within the original AppDomain. This is non-trivial but can generally be accomplished.

An alternative would be to use reflection to modify the static state field, assuming you are running tests with sufficient permission to do that. You would have to make sure that you didn't enable any parallelism in order to avoid multiple tests that change the shared state running at the same time.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the confirmation @Charlie!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.