开发者

How to run the same testmethods while only changing the dependencies?

开发者 https://www.devze.com 2022-12-17 17:35 出处:网络
I have 5 testmethods that test the functionality of a PasswordManager object开发者_开发技巧.I use the built in test engine of visual studio 2008. This manager can make use of two Dependencies: an XMLS

I have 5 testmethods that test the functionality of a PasswordManager object开发者_开发技巧.I use the built in test engine of visual studio 2008. This manager can make use of two Dependencies: an XMLStorageManager or a DbStorageManager. The Dependency is set in the Passwordmanager's constructor. How can I run the tests twice with the only difference the kind of StorageManager I use?

(I know, I know, these are NOT unit tests...)


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消