I have prepared some automatic tests with the Visual Studio Team Edition testing framework. I want one of the tests to connect to the database following the normal way it is done in the program:
string r_providerName = ConfigurationManager.ConnectionStrings["main_db"].ProviderName;
But I am receiving an exception in this line. I suppose this is happening because the ConfigurationManager is a singleton. How can you work around the singleton problem with unit tests?
Thanks for the replies. All of them have been very instructive.
First of all, extract an interface from the Singleton class and then apply Dependency Injection. We need interface for decoupling purpose and unit testing. Accessing singleton class from another class, the instance would then be passed to any objects that might trying to implement it through the property.
It's very difficult to write unit tests for code that uses singletons because it is generally tightly coupled with the singleton instance, which makes it hard to control the creation of singleton or mock it.
Making a class a singleton can make it difficult to test its clients, as it's impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type.
If your singleton contains mutable state that cannot be reset between tests, then it will affect unit testing as the tests will need to be run in a specific order and the state accounted for. If your singleton contains state that changes of time, it will prevent you reliably running tests in parallel.
Have a look at the Google Testing blog:
And also:
Finally, Misko Hevery wrote a guide on his blog: Writing Testable Code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With