How do I set up a test that checks validations only on update if the model has an association? Below are the 2 classes and the test.
user.rb
class User < ActiveRecord::Base
has_one :survey
validates :first_name, presence: true, on: :update, if: :survey_completed?
private
def survey_completed?
survey.present?
end
end
survey.rb
class Survey < ActiveRecord::Base
belongs_to :user
validates :user, presence: true
end
user_spec.rb
describe "if survey is completed" do
let(:user) {User.create(email: '[email protected]')}
let(:survey) {Survey.create(user_id: user.id)}
it "returns error if phone number has not been completed" do
user.first_name = 'test'
expect(user.reload.valid?).to be false
end
end
The above test fails, it returns true. Having looked in the console, I can see that the test is failing because there is no survey for my user, so the validations aren't being run.
I've tried variations with save!
, using reload, and not using reload and the test always returns true. How do I set up the test so that there is a survey associated with the user?
For simplicity, I've only shown the relevant code.
In rspec let
is lazy. It isn't evaluated until you use the variable in your code. Since your test does not have survey
in it, the line let(:survey) {Survey.create(user_id: user.id)}
is never run.
For this test, I would explicitly create a survey on user
(i.e. user.survey.create
) so the validation will run properly.