To make it short but clear, I'm working on a Rails app and I'm now testing my controllers.
I use FactoryBot to generate instances to work with, database cleaner (truncation) to clean up my database after each test, and Capybara to test my controllers, emulating the user actions.
Factory bot is working properly and I have my instances being generated correctly and I can interact with / test them.
Buyt here's my problem: Whenever I test the "Update" method of my controller, I expect the value of the selected attribute of my instance to be updated when clicking my "Save button". But when I use the p tag to check the value (Before and after clicking my "Save" button) nothing changed !
I've been spending the afternoon on this issue and wish someone could help me out to understand what I'm doing wrong...
Here's my code:
require 'rails_helper'
RSpec.describe "UserDetails", type: :controller do
render_views
describe "PATCH /update", focus: true do
before do
@user = create(:user, :amin)
@user_detail = create(:user_detail, :user_detail_user_2)
login_as(@user)
end
it "should be possible to update the user details" do
visit "/user_details/#{@user_detail.id}/edit"
expect(response).to have_http_status(:ok)
expect(page).to have_text("Edit your personal information")
expect(page.current_url).to match("/user_details/#{@user_detail.id}/edit")
p @user.user_detail.mobile_number # nil
p @user_detail.mobile_number # nil
expect(@user.user_detail.mobile_number.nil?).to be true
fill_in "user_detail[mobile_number]", with: "07 123 123"
expect(page).to have_button("Save")
click_link_or_button('Save')
expect(@user.user_detail.mobile_number).to eq("07 123 123") **#Failure/Error here**
end
end
end
Here's the Failure / Error I get:
Failures:
1) UserDetails PATCH /update should be possible to update the user details
Failure/Error: expect(@user.user_detail.mobile_number).to eq("071111111")
expected: "07 123 123"
got: nil
(compared using ==)
# ./spec/requests/user_details_controller_spec.rb:56:in `block (3 levels) in <top (required)>'
My user and user_detail instances both are valid with an id. There's no validation on the mobile_phone attribute, but I still want this value to get updated when clicking my "Save" button.
By the way, I tried running the test with js: true to checkCapybara cycle. Everything is happening properly. I even see the view being rendered with the new phone number being displayed. But when i checked the value in the _spec file, I still get nil as a value.
How can I fix that? Does anyone has the explanation of why it's not working?
Thank you very much in advance!
CodePudding user response:
I just found the solution... I post it here rather than deleting the post as I'm sure It'll help other people in the future (Including myself).
We need to use "your_instance.reload" between the moment you click the update / create button via Capybara, and the moment we want to test if the value of an attribute changed or not.
click_link_or_button('Save')
@user_detail.reload
expect(@user.user_detail.mobile_number).to eq("071111111")
Now the result in the console:
UserDetails
PATCH /update
nil
nil
"071111111"
"071111111"
should be possible to update the user details
Finished in 5.01 seconds (files took 8.98 seconds to load)
1 example, 0 failures
Literaly one simple word. And no one ever talked about it... I feel ridiculous.
Have an amazing day guys !