While writing some MSpec BDD tests I came across a scenario where a test that I was expecting to fail was passing, but only when I ran all of my tests. When I ran the test in isolation it failed as expected. After some investigation I found that some state that was set in a previous test was not being reset before the second test was running and this was causing the second test to pass when I expected it to fail. The following contrived code reproduces the scenario:
public class ContextBase
{
protected static object state;
}
public class Context_a : ContextBase
{
Establish context = () => { state = new object(); };
It should_set_state = () => state.ShouldNotBeNull();
}
public class Context_b : ContextBase
{
Establish context = () => { };
It should_set_state = () => state.ShouldNotBeNull();
}
Both of these test pass because Context_a is executed before Context_b and at the time Context_B is executed the state that was set in Context_A is still set. If you run Context_B in isolation then the test fails as the state has not been set. Interestingly if you remove the empty Establish statement from Context_B then Context_B will always fail as expected.
I'm relatively new to MSpec and this behaviour surprised me. I assumed that state like this would be reset between executing each context. Perhaps I have missed something... am I constructing these tests correctly? If MSpec does not reset state like this between contexts automatically then what strategy should I use to ensure that state is reset in cases like the one in my example? Should I put an Establish lambda on the ContextBase class that sets all state fields to null?