Gusto
Gusto

Reputation: 73

How do I stub a method for a class generated at run-time with Rails minitest?

I want to stub out a call to a 3rd party component, but finding this pretty challenging in Rails mini-test. I'll start with the most basic question above. Here is some very simplified pseudo code to better explain what I'm trying to do:

class RequestController < ActionController::Base
  def schedule
    # Parse a bunch of params and validate

    # Generate a unique RequestId for this request

    # Save Request stuff in the DB

    # Call 3rd party scheduler app to queue request action
    scheduler = Scheduler.new
    submit_success = scheduler.submit_request

    # Respond to caller
   end
 end

So I'm writing integration tests for RequestController and I want to stub out the 'scheduler.submit_request' call. My test code looks something like this:

def test_schedule_request
  scheduler_response = 'Expected response string for RequestId X'
  response = nil
  Scheduler.stub :submit_request, scheduler_response do
    # This test method calls the RequestController schedule route above
    response = send_schedule_request(TEST_DATA)
  end

  # Validate (assert) response
end

Seems pretty straightforward, but apparently I can't stub out a method for a class that doesn't exist (yet). So how do I stub out a class method for an object created at run-time in the code I'm testing?

Upvotes: 2

Views: 1227

Answers (2)

Gusto
Gusto

Reputation: 73

As Vimsha noted you have to first stub out the class initialization. I couldn't get his code to work, but this revised test code below has the same idea:

def test_schedule_request
  scheduler_response = 'Expected response string for RequestId X'
  response = nil
  scheduler = Scheduler.new
  Scheduler.stub :new, scheduler do
    scheduler.stub :submit_request, scheduler_response do
      # This test method calls the RequestController schedule route above
      response = send_schedule_request(TEST_DATA)
    end
  end

  # Validate (assert) response
end

Thanks, Dave

Upvotes: 1

usha
usha

Reputation: 29349

I am not sure about minitest. But in rspec, you will have to stub the initialization part as well and return a mocked scheduler object

This is how i would do it in rspec.

mock_scheduler = double("scheduler")
Scheduler.stub(:new).and_return(mock_scheduler)
mock_scheduler.stub(:submit_request).and_return(response)

Other option would be

   Scheduler.any_instance.stub(:submit_request).and_return(response)

Upvotes: 1

Related Questions