Reputation: 6684
I am trying to create a request spec for a form submission and my recaptcha verification is causing the test to fail. I have a pretty simple test:
RSpec.describe "PotentialClients", type: :request do
let(:pc_attributes) { ... }
describe "POST /potential_clients" do
it "should create record" do
expect { post potential_clients_path, params: { potential_client: pc_attributes } }
.to change(PotentialClient, :count).by(+1)
end
end
end
I run into an issue because in PotentialClients#create
I make a call to verify_recaptcha?
which returns false
in the test instead of true
:
# potential_clients_controller.rb
def create
@potential_client = PotentialClient.new(potential_client_params)
page_success = verify_recaptcha?(params[:recaptcha_token], 'lead_creation_page')
if page_success && @potential_client.save
...
end
end
# application_controller.rb
def verify_recaptcha?(token, recaptcha_action)
secret_key = ENV['CAPTCHA_SECRET_KEY']
uri = URI.parse("https://www.google.com/recaptcha/api/siteverify?secret=#{secret_key}&response=#{token}")
response = Net::HTTP.get_response(uri)
json = JSON.parse(response.body)
if json['success'] && json['score'] > RECAPTCHA_MINIMUM_SCORE && (json['action'] == "lead_creation_page" || json['action'] == "lead_creation_modal")
return true
elsif json['success'] == false && json["error-codes"].include?("timeout-or-duplicate")
return true
end
return false
end
How should I mock the call to verify_recapthca?
so that my test passes? I've tried:
allow(PotentialClient).to receive(:verify_recaptcha?).and_return(true)
# and
allow_any_instance_of(PotentialClient).to receive(:verify_recaptcha?).and_return(true)
but both threw errors:
PotentialClient(...) does not implement: verify_recaptcha?
Upvotes: 2
Views: 908
Reputation: 106037
allow(PotentialClient).to receive(:verify_recaptcha?).and_return(true)
This isn't working because—as the error message says—PotentialClient (the model) doesn't have a method called verify_recaptcha?
. The method is defined in ApplicationController, which is extended by PotentialClientsController, and that's where you need to mock it.
My Rails is rusty, but it looks like in an rspec-rails controller spec the current instance of the controller is exposed by the controller
method. In that case, what you want is this:
allow_any_instance_of(ApplicationController).to receive(:verify_recaptcha?).and_return(true)
Upvotes: 1