I am attempting to mock the following line:
publishers = AdminUser.where(can_publish: true).pluck(:email)
I have tried:
relation = instance_double('AdminUser::ActiveRecord_Relation')
allow(AdminUser).to receive(:where).with(can_publish: true).and_return(relation)
allow(relation).to receive(:pluck).with(:email).and_return(['email', 'email2'])
Unfortunately the expectation doesn't seem to match. No errors are thrown, but the methods aren't mocked .
I have also tried just and let pluck work.
allow(AdminUser).to receive(:where).with(can_publish: true).and_return([object, object2])
However, this expectation is too generate and fails when it where
matches another where
call higher in the code.
How can I mock this line?
Although you can use receive_message_chain
as suggested, treat the need for such complexity as an indication that your class's interface could be cleaner.
The RSpec docs say to consider any use of receive_message_chain a code smell .
A better approach would be to define a class method on AdminUser
named something like publisher_emails
, which which will be much simpler to stub, and also improves the readability of your code.
You can stub method calls on doubles:
require 'rails_helper'
RSpec.describe AdminUser, type: :model do
let(:expected) { ["a@example.com"] }
let(:relation) { double(pluck: expected) }
it "returns the expected value" do
allow(AdminUser).to receive(:where).with(can_publish: true).and_return(relation)
publishers = AdminUser.where(can_publish: true).pluck(:email)
expect(publishers).to eq expected
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.