【问题标题】:Test failing for feature that works using assert_changes使用 assert_changes 的功能测试失败
【发布时间】:2021-04-15 08:38:03
【问题描述】:

我的聊天应用有一个聊天类和一个消息类;当消息添加到聊天中时,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 %>

【问题讨论】:

  • 你必须使用assert_changes吗?
  • 有没有更好的方法来断言时间已更新?还是 assert_changes 在这里不起作用的原因?

标签: ruby-on-rails testing minitest


【解决方案1】:

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

assert_changes "@chat.reload.updated_at" do

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

【讨论】:

  • 这会做两个数据库查询吗?
【解决方案2】:

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

  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 指向内存中完全不同的对象。

【讨论】:

    猜你喜欢
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2021-01-23
    相关资源
    最近更新 更多