Search code examples
ruby-on-railstestingminitest

Test failing for feature that works using assert_changes


My chat app has a chat class and a message class; when a message is added to the chat, chat.updated_at should also be updated (achieved with belongs_to :chat, touch: true).

When I test this manually, it works correctly, the time is updated. My test below fails however, and I cannot work out why.

  test "sending a message should update chats updated timestamp" do
    sign_in @user
    assert_changes "@chat.updated_at" do
      post messages_path(params: { message: { 
        text: 'Hello', to_id: @bob.id, chat_id: @chat.id
        }})
      assert_response :success
    end
  end

I simply get the error @chat.updated_at didn't change.

My chat fixture is

one:
  id: 1
  subject: nil
  updated_at: <%= 2.hours.ago %>

Solution

  • I think you should use model.reload https://apidock.com/rails/ActiveRecord/Persistence/reload

    assert_changes "@chat.reload.updated_at" do
    

    Explanation: Once a Rails model is loaded from DB, when you access an attribute it will use the values that were already read and not make the same query again and again (unless explicitly told to do so with reload). And in your test, Ruby simply compares @chat.updated_at before and after but there is no second query on the second time, simply a cached attribute