user1028432
user1028432

Reputation: 137

Test module method with rspec-mocks

How to test config method in this module with Rspec 3 mocks?

module TestModule
  class << self
    attr_accessor :config
  end
  def self.config
    @config ||= Config.new
  end
  class Config
    attr_accessor :money_url
    def initialize
      @money_url = "https://example1.come"
    end
  end
end

I tried something like this:

describe "TestModule config" do
  it "should have config instance" do
    config = class_double("TestModule::Config")
    obj = instance_double("TestModule")
    allow(obj).to receive(:config).and_return(config)
    obj.config
    expect(obj.config).to eq(config)
  end
end

It looks, that it doesn't works, why ?

Failures:

1) TestModule config should have config instance Failure/Error: allow(obj).to receive(:config).and_return(config) TestModule does not implement: config # ./spec/config_spec.rb:41:in `block (2 levels) in '

Upvotes: 0

Views: 1221

Answers (2)

Dave N
Dave N

Reputation: 398

I believe you mixed up class_double and instance_double. Try switching them and see how it goes. (sent from mobile phone so forgive my brevity)

UPDATE: Now that I'm at a computer, I can dig into this a bit more. First, why are you stubbing the method you're testing? Aren't you trying to test that it returns an instance of the Config class? By stubbing the .config method, you're not really testing your method to prove that it does what you want it to do. I think you could really simplify this to something like:

RSpec.describe TestModule do
  describe ".config" do
    it "returns an Config instance" do
      expect(TestModule.config).to be_a TestModule::Config
    end
  end
end

Upvotes: 1

rafb3
rafb3

Reputation: 1702

I'd recommend testing the class directly with

describe "module config" do
  it "has config" do
    expect(TestModule.config).to be kind_of(TestModule::Config)
  end
end

If you don't need the .config to be changed by an outside object, then there's no need to have the attr_accessor :config as the def self.config already defines a accessible .config method to TestModule. If you want to allow .config to be changed from the outside, then just having a attr_writer :config should suffice as the reader/getter is already defined as that method.

Moreover, if you already have your class open with class << self, then declaring the .config method inside that would make more sense as it would contain all class level definitions. Just drop the self. from the beginning of the declaration so it reads def config as you are already "inside" the class.

Upvotes: 1

Related Questions