Testing the Singleton Nature

Focusing on the singleton nature, there are two essential behaviors and two optional behaviors we need to test. The two essential behaviors are

• That getInstance() returns an instance of the class

• That getInstance() returns the same instance for all invocations

Let’s address these and then talk about the optional behaviors. Note that we did not say anything about the initialized state of the instance. That is not part of the value added by the getInstance() method. Rather, it is part of the value added by the class member initialization and the constructor, which are a separate bundle of intents.

The second behavior, that the singleton always returns the same instance, is the behavior that makes singletons difficult to test. Why is that so?

The most common reason is that sharing an instance essentially forces us to use a Shared Fixture [xTP], whether we want to or not. While a shared fixture can be useful, a Fresh Fixture is always preferable to avoid test interactions as shared state is carried from one test to the next. Further, if you have tried to parallelize your tests on different threads, your shared instance will facilitate potential data collisions between the individual tests. All of this leads to Erratic Tests that will reduce your confidence in your test base and detract from your productivity as you continually diagnose and debug the failures.

To simply test the singleton behaviors, we can address this issue by testing both behaviors in a single test method (Listing 10-2).

Listing 10-2: Testing the essential behaviors of a singleton’s getInstance() method

@Test
public void testGetInstance() {
  Singleton sut = Singleton.getInstance();
  Assert.assertNotNull(sut);
  Assert.assertSame(sut, Singleton.getInstance());
}

The optional behaviors for the singleton implementation above are

• The lazy loading behavior—that is, getInstance() only allocates the object on the first request

• That getInstance() performs its allocation in a thread-safe way

These behaviors are common to many singleton implementations. We won’t address them directly here. Access coercion from Chapter 9 can be used to test lazy loading by providing access to the instance attribute. The thread-testing techniques from Chapter 13 may be used to verify the thread safety.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.27.171