When depended-on objects do not provide a common base type or interface that can be implemented by your test doubles, unit tests can not substitute out of the box. When the depended-on is in control of the developer, an interface can be added, however when the depended-on object is out of control (i.e. when provided via a third party library, Flash Player or Flex framework type the developer is not be able add an interface. However, with creating subclasses of depended-on objects, that are used in production code, developers can still substitute as shown via an examlple of flash.net.LocalConnection.
package com.adobe.ac.util.integration
{
import flash.net.LocalConnection;
public class LocalConnectionWrapper extends LocalConnection implements ILocalConnection
{
}
}
Singletons are often critisized as they represent global state and bind two different responsiblities by nature; the construction concern and the problem domain of the object. Opponents argue it should be other objects responsible for the fact that an object is allowed to be created once, twice or another number of times. The creation of objects is application dependent, and shouldn't concern the object itself.
However, Singletons are convenient, especially when no IoC framework is available, hence they are popular and hence we need to test them as well; like it or not.
When a test is changing any state of the Singleton, the test needs to reset the state of the Singleton to the original state after the test is finished. Unit tests are meant to be independent and shouldn't rely on tests that might or might not have run earlier. However, resetting a Singleton isn't possible by design. Depending on the way the Singleton is implemented in ActionScript developers might be successfull with using the new operator and benefit from the fact that ActionScript does not support private constructors. However, by design, Singletons are not resetable and if the Singleton implementation is more robust (i.e. using an inner class), the only way around resetting is to sacrifice the encapsulation of a Singleton. A public API that accesses the private instance variable or a Singleton subclass that accesses a protected private instance variable could be created.
If the object under test just uses a Singleton as depended-on object the Singleton would also need to be reseted once the state is changed.
As described above, also in this case, the private instance property of the Singleton could be declared protected and a Singleton test subclass could overwrite it. Where the test subclass is created doesn't matter but it is recommended to make clear that the instantiation of the test subclass is targeting at a specific Singleton and that the test also reverses this step once the unit test is complete.
Instead of subclassing the production Singleton, an often easier approach is to override the access to the Singleton in the object under test with an object subclassing the object under test. For that, the Singleton return type needs to be of an interface or base type and accessed from a protected method.
A ModelLocator of Cairngorm 1 and 2 can be substituted as long as the property on the ModelLocator is typed as an interface. Then, a simple overwrite (set) with a test double can perform the substitution. After the test, the overwrite should be reversed.