praga2050
praga2050

Reputation: 773

Unable to test a method inside a module in Rspec unit testing for Rails

This is my module. I like to test method load_csv

I referred this example Example Link

and wrote this code. Below is the module Code

require 'csv'

module DummyModule
  class Test
    def load_csv(filename)
      CSV.read(filename, :row_sep => "\r", :col_sep => "\t")
    end
  end
end

this is my Rspec

require 'spec_helper'

describe DummyModule do
  let(:data) { "title\tsurname\tfirstname\rtitle2\tsurname2\tfirstname2\r" }
  let(:result) { [["title", "surname", "firstname"], ["title2", "surname2", "firstname2"]] }
  before(:each) do
    @attribute_validator = TestAttributeValidator.new

  end

  it "should parse file contents and return a result" do
    puts data.inspect
    puts result.inspect
    File.any_instance.stubs(:open).with("filename","rb") { StringIO.new(data) }
    @attribute_validator.load_csv("filename").should eq(result)
  end
end

class TestAttributeValidator
  include DummyModule
end

It gives me this error

DummyModule should parse file contents and return a result
 Failure/Error: @attribute_validator.load_csv("filename").should eq(result)
 NoMethodError:
   undefined method `load_csv' for #<TestAttributeValidator:0xd0befd>
 # ./spec/extras/dummy_module_spec.rb:15:in `(root)'

Pls Help

Upvotes: 1

Views: 751

Answers (2)

Patru
Patru

Reputation: 4551

(Adding another answer as this is really another question)

Googling for Errno::ENOENT leads to this answer, but that should hardly be necessary as the error message is really telling, your file was not found. Since you stubbed for "filename" it should be found if the version of CSV you are using still uses open to open the file (which the current ruby CSV reader seems to do, see the source) then it actually should work.

However depending on your version of ruby the CSV library might add some more options, the version I referenced merges universal_newline: false to the options for open, so your stub would not have all the parameters it expects and forward your call to the "regular" method which does not find your "filename". You should check your exact version of ruby and stub accordingly.

That is probably part of the legacy that comes with such a dynamic language as ruby :-)

Upvotes: 1

Patru
Patru

Reputation: 4551

You probably do not want your

class Test

inside your module definition. Like this the following would work:

@attribute_validator_tester = TestAttributeValidator::Test.new
@attribute_validator_tester.respond_to? 'load_csv'
=> true

but that is probably not what you intended. Including a module into a class will add all the 'features' of the module (that is all the methods, but also constants, and classes) to the class the module is included in. In your example you added the class Test to the namespace of class TestAttributeValidator and the instances of this class would have the method load_csvyou desire.

Just omit the class definition inside your module and all will be well.

Upvotes: 2

Related Questions