Why is it hard to unit test a system that depends on singletons?

前端 未结 7 1839
Happy的楠姐
Happy的楠姐 2020-12-02 23:41

I\'ve read cases for and against using the singleton pattern. One common case against describes the difficulties in unit testing with singletons, but I\'m unclear as to why

相关标签:
7条回答
  • 2020-12-02 23:50

    TL;DR The same object is shared between all tests, which can become a pain.

    If the singleton holds some state, and you run multiple tests on it, then the ordering of the tests may become an issue. Imagine a singleton "MailStore", which holds a list of messages. I want to write a unit test for listing mails, and another for deleting them.

    Of course if the "list" runs before the "delete", perhaps that is ok. If the "delete" runs before the "list", then we struggle because there is nothing to delete. (The results change depending on the order in which the tests are run.)

    0 讨论(0)
  • 2020-12-02 23:50

    I don't recall ever reading that, but I suspect the problem is the fact that you can only create one. In some cases, that may not be a problem, just test it normally.

    But what if you want to create and test a different one, perhaps with different constructor/factory method parameters? Do you restart the JVM? Or create your singleton so that it's not really a singleton and can be reset? Not good.

    0 讨论(0)
  • 2020-12-02 23:51

    A great article about this is Singletons are Pathological Liars. This describes, using a simple example, why testing using singletons is unexpectedly hard.

    0 讨论(0)
  • 2020-12-02 23:54

    If you reference a singleton class that exists outside of the class under test, then you no longer have a true unit test. Instead of testing a single unit - the target class - you're now testing two units - the target class and the singleton.

    There's also the fact that singleton objects tend to have state. For unit tests to be repeatable, those state changes need to be rolled back when the unit test is complete. Alternatively, you have to create a mock version of the singleton that's destroyed after each test is run. Either adds a fair amount of overhead, both in source code and in running time.

    0 讨论(0)
  • 2020-12-02 23:54

    Singletons are a problem for several reasons:

    • They're a special case of a Service Locator, which provides a mechanism to "get me one of those" that isn't necessarily easy to override when needed.
    • They provide an entry point to read or write global variables. Wrapping those global variables up in an object with only one instance that is globally accessible via the Singleton pattern doesn't magically make them stop being global variables.
    • They're trouble for maintenance too. For example, what happens when they stop being a true Singleton -- maybe you have to access two databases instead of "the database"?
    0 讨论(0)
  • 2020-12-02 23:59

    Because the singleton is an OOPish global variable. Basically, all functions relying on the use of the singleton (directly or indirectly) are not guaranteed to be deterministic (i.e. you cannot expect the function to return the same outputs for the same inputs T each and every run).

    0 讨论(0)
提交回复
热议问题