Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing singletons

I have a singleton that contains reference to statistics object.

When I run couple of unit test on the program that uses that singleton - the values sustained between the tests.

I though that when I'm doing Program.Main() it all starts over between unit tests, but somehow it remembers the results from last test.

How can I write unit tests that will be isolated from each other (I don't want clean() functions - I want it to start over with new "everything"),

like image 810
Eyal Avatar asked May 05 '11 12:05

Eyal


People also ask

Why are singletons difficult to unit test?

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.

What is a singleton test?

The Singleton pattern is a useful pattern in Android development, and Java development at large. The Singleton pattern is defined as follows: In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.

How do singleton affect testing?

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.

How do you mock singletons and static methods in unit testing?

Just use Reflection. With provided sample code you need to make sure the static constructor is called before setting the static field to the mocked object. Otherwise it might overwrite your mocked object. Just call anything on the singleton that has no effect before setting up the test.


1 Answers

I wrote a post about that here: http://pvlerick.github.io/2017/03/how-to-get-rid-of-a-singleton

TL;DR:

  1. Extract an interface from the Singleton (even if you don't own it) and make your class work against that interface instead of the Singleton's instance;
  2. Depending on whether you own the Singleton or not, you can make it implement that interface or you'll need a simple adapter.
like image 96
Philippe Avatar answered Oct 04 '22 05:10

Philippe