I am new to RSpec. I want to test my search controller. I try to stub my search method in the controller but it always fails.
Failure/Error: expect(Doctor).to receive(:search).with(search_param)
(<Doctor(id: integer, name: string, address: string, phone: string, is_active: boolean, field_id: integer, created_at: datetime, updated_at: datetime, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: inet, last_sign_in_ip: inet, roles: integer, description: text, avatar_file_name: string, avatar_content_type: string, avatar_file_size: integer, avatar_updated_at: datetime, avatar_processing: boolean, title: string, valid_doctor: boolean, verification_photo_file_name: string, verification_photo_content_type: string, verification_photo_file_size: integer, verification_photo_updated_at: datetime) (class)>).search("rizky")
expected: 1 time with arguments: ("rizky")
received: 0 times
What's the correct way to isolate Searchkick?
Here is my search method in the controller:
def search
@doctors = []
keyword = params[:keyword]
@doctors = call_search_in_doctor(keyword) if keyword.present?
respond_to do |format|
format.json { render json: @doctors, status: 200 }
format.html { render 'users/search/index.html.haml', status: 200 }
end
end
def call_search_in_doctor(keyword)
Doctor.search keyword,
misspellings: { edit_distance: 3 },
page: params[:page],
per_page: 10,
limit: 100,
fields: [{ name: :word },
{ name: :word_start },
{ name: :word_middle },
{ name: :word_end },
:code, :field_name]
end
And here is my controller test:
context 'with keyword' do
let(:search_param) { "rizky" }
let(:doctor) { instance_double(Doctor) }
let(:results) { instance_double(Searchkick::Results) }
before do
allow(Doctor).to receive(:search).with(search_param) {:results}
end
it 'calls Doctor.search' do
get :search, search_param
expect(Doctor).to receive(:search).with(search_param)
end
end
Thanks for your precious time!
RSpec isn't saying that Doctor.search
wasn't called, it's saying that it wasn't called with the arguments you specified. Your production code calls Doctor.search
with two arguments (the search term and the hash of parameters), but your test allows Doctor.search
to be called with only one argument (the search term).
You can fix it either by
with
calls in your test (if you think it's relevant to the test to check what that hash is), oranything
to those calls (if you think the hash is irrelevant to the test and just want to ignore it)