RSpec controller test error: controller does not i

2019-07-08 09:59发布

问题:

I've written some custom code for Devise registration. Namely once a user hits the "sign up" button, Devise's generic code ensures that the user is saved correctly. But then, I want to go in and make sure that the user gets an associated Stripe customer account. Most of the code below is from Devise, except for a few lines that I added:

class Users::RegistrationsController < Devise::RegistrationsController
def create
  build_resource(sign_up_params)
  resource.save
  yield resource if block_given?
  if resource.persisted?
    #### If statement below is the key custom code ####
    if create_stripe_customer
      #### Back to default Devise code ####
      if resource.active_for_authentication?
        set_flash_message :success, :signed_up if is_flashing_format?
        sign_up(resource_name, resource)
        respond_with resource, location: after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    #### Else statement below is custom ####
    else
      flash[:danger] = flash_messages["not_your_fault"]
      redirect_to root_path
    end
  else
    clean_up_passwords resource
    set_minimum_password_length
    respond_with resource
  end
end 

private

def create_stripe_customer
  new_stripe_customer = StripeService.new({
    source: sign_up_params[:token],
    user_id: self.id 
  })    
  if new_stripe_customer && self.update_attributes(stripe_customer_id: new_stripe_customer.id)
  else
    false
  end
end
end

I'm trying now to write tests on the create controller to make sure that upon a post to create, my custom method:

  1. Gets the right parameters (i.e., there are other tests to make sure that the method does the right things with those parameters), and returns true, whereby then the user is redirected to the after_sign_up_path. In this example, the right parameter is that the sign_up_params[:token] is being passed through to create_stripe_customer
  2. Gets the wrong parameters and returns false, whereby the user is redirected to the root_path as per my custom code

This is my RSpec file so far:

describe Users::RegistrationsController, "Create action" do

  before do
    request.env['devise.mapping'] = Devise.mappings[:user]
  end

  it "Successful creation" do
    Users::RegistrationsController.should_receive(:create_stripe_customer).with(source: "test" , user_id: @user.id).and_return(false)
    post :create, sign_up: { first_stripe_token: "test" }
  end
end

When I run it however, I get:

Failure/Error: Users::RegistrationsController.should_receive(:create_stripe_customer).with(source: "test" , user_id: @user.id).and_return(false)
   Users::RegistrationsController does not implement: create_stripe_customer

Not sure why the controller is not implementing the method...

回答1:

You're stubbing create_stripe_customer as a class method, but it's actually an instance method.