Sandip Ransing
Sandip Ransing

Reputation: 7733

How to stub a instance method for a specific instance?

I have below case,

class Schools::Status
  def initialize(school)
    @school = school
  end

  def active?
    true
  end
end

Now, I want to stub active? method for a specific school.

One way to have like this

Schools::Status.new(school).stubs(:active?).returns(false)

But my use case is different, I have search result of schools and I want to filter that result based on active? value as below:

schools.select { |s| Schools::Status.new(school).active? }

In above case, specifically I want to stub active? for certain instance.

Upvotes: 2

Views: 1966

Answers (2)

Sandip Ransing
Sandip Ransing

Reputation: 7733

I found answer on myself and putting here so that others can be benefited

Lets say, I have school for which active? method of Schools::Status is to be stubbed.

In order to achieve this, First we need to stub new method of Schools::Status so that it will return Schools::Status instance which we want and it can be done as below -

status = Schools::Status.new(school)
# now whenever Schools::Status instance getting created for ours school 
# it will return our defined status instance
Schools::Status.stubs(:new).with(school).returns(status)

Secondly, we have to stub active? method for status instance -

status.stubs(:active?).returns(false)

Now, filter will reject specified school for which active? method returns false

Upvotes: 1

hahcho
hahcho

Reputation: 1409

Just monkey-patch your class in the spec.The more rspec-way would be to use any_instance with stub but the problem is you cannot get access to the self of the stubbed instance so you practicly have no information about the school and you cannot access it in that block. Example:

Status.any_instance.stub(:active?) { # no way to access school }

Upvotes: 3

Related Questions