Testing Singletons with Ruby
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 MySingleton.reset_instance):
irb(main):026:0> MySingleton.instance => #<MySingleton:0x396fc> irb(main):027:0> MySingleton.reset_instance => MySingleton irb(main):028:0> MySingleton.instance => #<MySingleton:0x1cd04>
Leave a Reply