views:

684

answers:

1

I'm adding more rspec testing to my app and would like to test a ScoringMethods module, which is in /lib/scoring_methods.rb. So I added a /spec/lib directory and added scoring_methods_spec.rb there. I required spec_helper and set up the describe block as so:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe ScoringMethods do

  describe "should have scorePublicContest method" do
    methods = ScoringMethods.instance_methods
    methods[0].should match(/scorePublicContest/)
  end
end

Now methods[0] is a String and there is no problem matching the public method name with the regular expression. And the relative path to "spec_helper" is correct.

The problem is that the entire setup doesn't seem to use the rspec library. Running the example yields:

  ./spec/lib/scoring_methods_spec.rb:7: undefined method `match' for Spec::Rails::Example::RailsExampleGroup::Subclass_1::Subclass_1:Class (NoMethodError)
     ...

The entire Expectation and Matcher support seems to be missing. To test my supposition, I changed a working helper spec by replacing "is_instance_of" to "is_foobar_of". That test simply fails and says "is_foobar_of" is not a method of the targeted object; that it, this entire Spec::Rails::Example... hierarchy isn't present.

I've tried using other matchers as well. I've tried "be_instance_of" and some others. It seems that I'm not including the rspec library properly.

Finally, ScoringMethods is a module, just the same way Helpers are modules. So I thought that it would be possible to test a module (as opposed to classes, such as Controllers and Models).

I'd greatly appreciate your thoughts on what I've done wrong. Perhaps there is a more effective way of testing library modules? Thanks!

A: 

You should include your test block in an "it" block. For example:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe ScoringMethods do

  describe "should have scorePublicContest method" do
    it "should have a scorePublicContest method" do
      methods = ScoringMethods.instance_methods
      methods[0].should match(/scorePublicContest/)
    end
  end
end

You will find that the methods names returned aren't guaranteed to be in the order they exist in the file.

A model we often use when testing Modules is to include the module in either a class created for the test (inside the spec file) or included inside the spec itself.

Mark Morga
Mark,Thanks so much for responding. You're absolutely right! I didn't have the "it" block. Many thanks,Peter
Peter Degen-Portnoy
Also, thanks for your thoughts on testing Modules. The module is included in a class to expose only its public methods and to not get a huge list of methods returned when using the instance_methods call. This way, we can add new public methods to the module and they are available for selection in drop-down lists and the like. Using the same mechanism, as you suggest, will be helpful for testing.
Peter Degen-Portnoy