Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing Ruby Modules with rspec

Tags:

ruby

rspec

I'm having a bad time finding on SO/Google this particular case. I have a module with functions and in order to use them, you have to create a Class which includes/extends the Module depending if you'll want instance methods or class methods.

module A
  def say_hello name
    "hello #{name}"
  end

  def say_bye
    "bye"
  end
end

How can I test this module using rspec?

I have something like this, and I'm not sure where is the point I should create the class and extend Module.

describe A do
  class MyClass
    extend A
  end

  before(:each) { @name = "Radu" }

  describe "#say_hello" do
    it "should greet a name" do
      expect(Myclass.say_hello(@name)).to eq "hello Radu"
    end
  end
end

Thank you!

like image 680
radubogdan Avatar asked Dec 07 '14 10:12

radubogdan


1 Answers

You can create an anonymous class in your tests:

describe A do
  let(:extended_class) { Class.new { extend A } }
  let(:including_class) { Class.new { include A } }

  it "works" do
    # do stuff with extended_class.say_hello
    # do stuff with including_class.new.say_hello
  end
end

To see something similar in real code, I've used this strategy for testing my attr_extras lib.

That said, include and extend are standard features of Ruby, so I wouldn't test that every module works both when including and when extending – that's usually a given.

If you create a named class in the test, like you do in your question, I believe that class will exist globally for the duration of your test run. So this class will leak between every test of your test suite, potentially causing conflicts somewhere.

If you use let to create an anonymous class, it will only be available inside this particular test. There is no global constant pointing to it that could conflict with other tests.

like image 158
Henrik N Avatar answered Sep 22 '22 13:09

Henrik N