How to Test Ruby Modules With Rspec
What are Ruby modules
Modules are a way to share code either by re-using your own code, or using third party libraries (i.e., gems).
They help you group together methods, classes, and constants inside a namespace so that they are isolated from other modules.
module Generic def self.greeting puts "Hello World" end end module Specific def self.greeting puts "Hello John" end end Generic.greeting Specific.greeting # output Hello World Hello John
In the example above, even though the two methods have the same names, you can still use both because they belong to different namespaces.
How are Ruby modules used
You can use modules on their own (just as you saw in the previous example), to group methods that don’t really fit anywhere else. To call a module method, you specify the name of the module, and the name of the method, separated by a dot. Like this:
But you can also include modules into classes so that those classes inherit all the module’s instance methods.
module Greet def greeting puts "Hello World" end end class Person include Greet end Person.new.greeting # output Hello World
How to test a Ruby module with RSpec
For module methods (i.e., those declared on
self), the tests are similar to class method tests.
require 'spec_helper' module MyMath def self.number 5 end end RSpec.describe MyMath do it 'returns five' do expect(MyMath.number).to eq(5) end end
But when you have a module that you include in other classes (i.e., it contains instance methods) the way you test it might not be obvious. An example should help with this challenge.
require 'spec_helper' module MyMath def number 5 end end class DummyClass include MyMath end RSpec.describe MyMath do it 'returns five' do dc = DummyClass.new expect(dc.number).to eq(5) end end
DummyClass includes the
MyMath module, it behaves like any other class that would include it. So by having a test that covers
DummyClass, you’ve covered all those other classes that include the module.
Another way you can do it, without including the module is to extend an object.
require 'spec_helper' module MyMath def number 5 end end class DummyClass end RSpec.describe MyMath do it 'returns five' do dc = DummyClass.new dc.extend(MyMath) expect(dc.number).to eq(5) end end
Testing modules in Ruby should be easier now that you’ve see a few examples.