Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stub helper method for request spec in rails / rspec

I have a helper method called get_books_from_amazon that does an API call and returns an array of books. I can't figure out how to stub it out in my request specs.

module BooksHelper
  def get_books_from_amazon(search_term)
    ...
  end
end

class StaticController < ApplicationController
  include BooksHelper
  def resources
    @books = get_books_from_amazon(search_term)
  end
end

I have tried the following in my spec, each to no avail:

# spec/requests/resource_pages_spec.rb
...
describe "Navigation" do
  it "should do such and such" do
    BooksHelper.stub!(:get_books_from_amazon).and_return(book_array)
    StaticHelper.stub!(:get_books_from_amazon).and_return(book_array)
    ApplicationHelper.stub!(:get_books_from_amazon).and_return(book_array)
    StaticController.stub!(:get_books_from_amazon).and_return(book_array[0..4])
    ApplicationController.stub!(:get_books_from_amazon).and_return(book_array[0..4])
    request.stub!(:get_books_from_amazon).and_return(book_array)
    helper.stub!(:get_books_from_amazon).and_return(book_array)
    controller.stub!(:get_books_from_amazon).and_return(book_array)
    self.stub!(:get_books_from_amazon).and_return(book_array)
    stub!(:get_books_from_amazon).and_return(book_array)

    visit resources_path
    save_and_open_page
  end

Any ideas on what the problem is?

like image 381
Tyler Avatar asked Dec 12 '22 21:12

Tyler


2 Answers

Kendick's response is good advice in this situation.

I've added this in case anyone is actually looking for an answer to the original question:

ActionView::Base.any_instance.stub(:helper_method) { "substitute return value" } 
like image 198
RobinGower Avatar answered Jan 07 '23 18:01

RobinGower


Helpers are typically used to clean up presentation "logic", so I wouldn't put something like a call to Amazon's API in a helper method.

Instead, move that method to a plain old Ruby class which you can call from your controller. An example might be:

class AmazonBookRetriever
  def get_books_from_amazon
    #code here
  end
end

Then your controller can call it:

def resources
  @books = AmazonBookRetriever.new.get_books_from_amazon(params[:search_term])
end

This should make mocking a lot easier. You can stub #new on the AmazonBookRetriever to return a mock, and verify that it receives the get_books_from_amazon message.

like image 39
Kenrick Chien Avatar answered Jan 07 '23 19:01

Kenrick Chien