Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stub a class method with a class_double in RSpec?

I’m trying to write a simple isolated test for a controller method in my Rails 4 app. The method takes an ID from a query string, asks the Project model to give me some rows from the persistence layer, and render the result as JSON.

class ProjectsController < ApplicationController

  def projects_for_company
    render json: Project.for_company(params[:company_id])
  end

end

I’m struggling with stubbing the for_company method. Here is the code I’m trying:

require "rails_helper"

describe ProjectsController do

  describe "GET #projects_for_company" do

    it "returns a JSON string of projects for a company" do
      dbl = class_double("Project")
      project = FactoryGirl.build_stubbed(:project)
      allow(dbl).to receive(:for_company).and_return([project])
      get :projects_for_company
      expect(response.body).to eq([project].to_json)
    end

  end

end

Since I’ve stubbed the for_company method, I expect the implementation of the method to be ignored. However, if my model looks like this:

class Project < ActiveRecord::Base

  def self.for_company(id)
    p "I should not be called"
  end

end

…Then I can see that I should not be called is actually printed to the screen. What am I doing wrong?

like image 730
Jezen Thomas Avatar asked Oct 05 '14 11:10

Jezen Thomas


People also ask

What is stubbing in RSpec?

In RSpec, a stub is often called a Method Stub, it's a special type of method that “stands in” for an existing method, or for a method that doesn't even exist yet. Here is the code from the section on RSpec Doubles − class ClassRoom def initialize(students) @students = students End def list_student_names @students.

What is double in RSpec?

A Double is an object which can “stand in” for another object. You're probably wondering what that means exactly and why you'd need one. This is a simple class, it has one method list_student_names, which returns a comma delimited string of student names.

What is an instance double?

An instance_double is the most common type of verifying double. It takes a class name or. object as its first argument, then verifies that any methods being stubbed would be present. on an instance of that class.

What is allow in RSpec?

Use the allow method with the receive matcher on a test double or a real. object to tell the object to return a value (or values) in response to a given. message. Nothing happens if the message is never received.


1 Answers

class_double doesn't actually replace the constant. You can call as_stubbed_const to replace the original

class_double("Project").as_stubbed_const

This is the just a convenience wrapper around stub_const

like image 188
Frederick Cheung Avatar answered Oct 20 '22 09:10

Frederick Cheung