Just a thought, but you could perhaps create an ordered test and add the same tests twice: add all tests once, then all tests again in the same order. In your test context keep a count of the number of times each test has been run. I believe that the context is static so it should only be created once, then reused as more tests are run. In the test set up, use the XmlStorageManager
if the test count is even and the DbStorageManager
if the test count for that test is odd.
I'm not an MSTest user, but you probably have a few options. Normally with NUnit I'd use a generic or parametrised fixture, but I'm not sure whether MSTest has similar capabilities. In light of this, here's how I'd do this with NUnit, in a form that should be reproducible using any unit test framework via the template method pattern.
Steps:
- Define an abstract base class with all of the tests in it
- Put in an abstract method called CreateStorageManager() that returns an IStorageManager (or whatever interface the two dependencies implement)
- Subclass the fixture twice and provide an implementation of CreateStorageManager() that returns the concrete type you wish to use to run the tests.
Here's the code for the equivalent NUnit version; I'm sure you can extrapolate. Note: The inheritance rules for MSTest may differ slightly from what I'm used to. If it doesn't work, you could try marking the base class as a test fixture.
public abstract class PasswordManagerFixtureBase
{
protected abstract IStorageManager CreateStorageManager();
// all tests go in this fixture
[Test]
public void SomeTestOrOther()
{
var passwordManager = CreatePasswordManager();
// do test logic
}
private PasswordManager CreatePasswordManager()
{
// calls into subclass implementation to get instance of storage
IStorageManager storage = CreateStorageManager();
return new PasswordManager(storage);
}
}
// Runs the tests in the fixture base using XmlStorageManager
[TestFixture]
public class PasswordManager_XMLStorageManagerImplTests
{
protected override IStorageManager CreateStorageManager()
{
return new XMLStorageManager();
}
}
// Runs the tests in the fixture base using DbStorageManager
[TestFixture]
public class PasswordManager_DbStorageManagerImplTests
{
protected override IStorageManager CreateStorageManager()
{
return new DbStorageManager();
}
}
There may be a more elegant way to do this with MSTest, but this should work.
If a PasswordManager
has a dependency like IStorageManager
which is being injected (DI, IoC, etc.) then it could be enough to mock this interface instead of using concrete implementation so there is no need to test PasswordManager
for both XML and Db realizations which could be tested separately from PasswordManager
.