December 11th, 2006
Testing a Singleton class is a bit tricker than you might expect. When testing, you typically need to reset the state of the objects in question in between tests. But this is something that a Singleton, by its nature, should never allow.
To solve this problem, you can make use of Ruby's open classes and add the following before your tests:
require 'singleton' class <<Singleton def included_with_reset(klass) included_without_reset(klass) class <<klass def reset_instance Singleton.send :__init__, self self end end end alias_method :included_without_reset, :included alias_method :included, :included_with_reset end
This code adds a class method when Singleton is mixed into your target class. This method
reset_instance effectively removes the instance, so you can start again.
In your tests, when you need to start over with a Singleton, just send
reset_instance to the singleton class. The following demonstrates this (note that the instance is a different object after
irb(main):026:0> MySingleton.instance => #<MySingleton:0x396fc> irb(main):027:0> MySingleton.reset_instance => MySingleton irb(main):028:0> MySingleton.instance => #<MySingleton:0x1cd04>