I have this situation, in which I define an instance method which returns a “safe to tamper” testing dummy of the class itself.
require 'test/unit'
require 'shoulda'
module TestExtension
def provides_tested_class_dummy
self.class_exec do
def tested_class_dummy
txt = "class #{@tested_class.name}Dummy < #{@tested_class.name}; end"
sub = self.singleton_class.class_eval txt
duplicated = sub.dup
duplicated.class_exec do
# do evil things to the dummy,
# such as redefining constants and stubbing methods
end
end
end
end
end
Test::Unit::TestCase.extend TestExtensions
Pleas don’t laugh yet. I’m doing this because it works for what I need to do, namely to test classes and do bad things to their dummies without touching the the tested classes in any way.
class SomeClass
# define some constants
# define some methods
end
Then, testing it:
class SomeClassTest < Test::Unit::TestCase
@tested_class = ::SomeClass
provides_tested_class_dummy()
should "somehow comply" do
dummy = tested_class_dummy()
assert_kind_of Module, dummy
# other assertions about the dummy's behavior
end
end
Now you can start laughing.
My main question is, in the line “duplicated = sub.dup”, where I duplicate the subclassed tested class, does that line make any sense? From me, it’s voodoo, I’m doing it just to minimize any negative effects of the tampering done to the dummy on the tested class itself. Am I gaining anything by #dup-ping a class?
Side question: If I’m doing something blatantly laughable, please tell me. I simplified this code and I am not really sure how it would work (the more complicated original does work as intended for me), but I hope you can at least get the idea. Also, please, wizards there, recommend me a good mocking framework.
If you want to do things like change constants or other class-wide data without trampling on the original class, dupping it looks to be the way to go –