Search code examples
ruby-on-railstestingcapybarafactory-botrspec-rails

When clicking update button with Capybara gem, my instance is not being updated [Rails / Rspec/ Testing]


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!


Solution

  • 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 !