Reputation: 2974
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 %>
Upvotes: 0
Views: 573
Reputation: 102046
You need to reload the record from the database to get the object in your test to reflect the changes that were performed in the database:
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
}})
@chat.reload
assert_response :success
end
end
Remember that @chat
in your test and controller point to completely different objects in memory.
Upvotes: 0
Reputation: 7878
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
Upvotes: 1