Rails: How do I write tests for a ruby module?
IMHO, you should be doing functional test coverage that will cover all uses of the module, and then test it in isolation in a unit test:
setup do @object = Object.new @object.extend(Greeter)endshould "greet person" do @object.stubs(:format).returns("Hello {{NAME}}") assert_equal "Hello World", @object.greet("World")endshould "greet person in pirate" do @object.stubs(:format).returns("Avast {{NAME}} lad!") assert_equal "Avast Jim lad!", @object.greet("Jim")end
If your unit tests are good, you should be able to just smoke test the functionality in the modules it is mixed into.
Or…
Write a test helper, that asserts the correct behaviour, then use that against each class it's mixed in. Usage would be as follows:
setup do @object = FooClass.newendshould_act_as_greeter
If your unit tests are good, this can be a simple smoke test of the expected behavior, checking the right delegates are called etc.
Use inline classes (I am not doing any fancy flexmock or stubba/mocha usage just to show the point)
def test_should_callout_to_foo m = Class.new do include ModuleUnderTest def foo 3 end end.new assert_equal 6, m.foo_multiplied_by_two end
Any mocking/stubbing library out there should give you a cleaner way to do this. Also you can use structs:
instance = Struct.new(:foo).new class<<instance include ModuleUnderTest end instance.foo = 4
If I have a module that is being used in many places I have a unit test for it which does just that (slide a test object under the module methods and test if the module methods function properly on that object).
What I like to do is create a new host class and mix the module into it, something like this:
describe MyModule do let(:host_class) { Class.new { include MyModule } } let(:instance) { host_class.new } describe '#instance_method' do it 'does something' do expect(instance.instance_method).to do_something end endend