使用 assert_changes 的功能测试失败

Test failing for feature that works using assert_changes

我的聊天应用程序有聊天 class 和消息 class;当一条消息被添加到聊天中时,chat.updated_at 也应该更新(通过 belongs_to :chat, touch: true 实现)。

当我手动测试时,它工作正常,时间已更新。然而,我下面的测试失败了,我不知道为什么。

  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

我只是得到错误 @chat.updated_at 没有改变。

我的聊天工具是

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

我认为你应该使用 model.reload https://apidock.com/rails/ActiveRecord/Persistence/reload

assert_changes "@chat.reload.updated_at" do

说明: 从数据库加载 Rails 模型后,当您访问属性时,它将使用已读取的值,而不是一次又一次地进行相同的查询(除非明确告知要重新加载)。在您的测试中,Ruby 只是比较前后的 @chat.updated_at 但第二次没有第二次查询,只是一个缓存属性

您需要从数据库重新加载记录以获取测试中的对象以反映在数据库中执行的更改:

  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

请记住,@chat 在您的测试和控制器中指向内存中完全不同的对象。