ruby-on-rails - Rspec期望更改计数不起作用

标签 ruby-on-rails rspec capybara rspec-rails actioncable

这里我正在测试 current_user.messages.count 中的更改当前用户发送有效消息后。这是我的代码:

规范

scenario 'adds to their messages', js: true do
  expect { find('#message_content').send_keys(:enter) }.to \
    change(current_user.messages, :count).by(1)
end

测试日志
# ...
ConversationChannel is transmitting the subscription confirmation
ConversationChannel is streaming from conversation_channel_1
   (0.6ms)  SELECT COUNT(*) FROM "messages" WHERE "messages"."user_id" = $1  [["user_id", 1]]
ConversationChannel#send_message({"content"=>"foobar\n", "conversation_id"=>"1"})
   (0.3ms)  BEGIN
   (0.9ms)  SELECT COUNT(*) FROM "messages" WHERE "messages"."user_id" = $1  [["user_id", 1]]
  Conversation Load (1.6ms)  SELECT  "conversations".* FROM "conversations" WHERE "conversations"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.7ms)  SELECT "users"."id" FROM "users" INNER JOIN "user_conversations" ON "users"."id" = "user_conversations"."user_id" WHERE "user_conversations"."conversation_id" = $1  [["conversation_id", 1]]
  SQL (1.0ms)  INSERT INTO "messages" ("content", "user_id", "conversation_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["content", "foobar\n"], ["user_id", 1], ["conversation_id", 1], ["created_at", "2018-01-29 11:27:13.095277"], ["updated_at", "2018-01-29 11:27:13.095277"]]
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-01-29 19:27:13 +0800
ConversationChannel stopped streaming from conversation_channel_1
   (0.2ms)  BEGIN
   (58.8ms)  COMMIT
   (16.7ms)  ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL;ALTER TABLE "conversations" DISABLE TRIGGER ALL;ALTER TABLE "messages" DISABLE TRIGGER ALL;ALTER TABLE "user_conversations" DISABLE TRIGGER ALL;ALTER TABLE "users" DISABLE TRIGGER ALL
  Rendered messages/_message.html.erb (0.6ms)
[ActionCable] Broadcasting to conversation_channel_1: {:message=>"<p>User 1: foobar\n</p>\n"}
# ...

规范失败 expected #count to have changed by 1, but was changed by 0即使在日志中显示 INSERT INTO实际发生。

最佳答案

这不起作用,因为您没有等待足够长的时间来实际发生消息添加。 send_keys浏览器收到按键事件后立即返回,但对浏览器中该按键触发的任何请求/ Action 一无所知。这就是为什么直接数据库访问测试在功能/系统测试中通常是一个坏主意(通常应该只测试用户可见的更改/交互)并且作为请求或 Controller 更有意义。

话虽如此,您可以通过在发送 key 后休眠来解决此问题,但更好的解决方案是使用 Capybara 提供的匹配器之一(具有等待/重试行为)来同步测试。

scenario 'adds to their messages', js: true do
  expect do 
    find('#message_content').send_keys(:enter) }
     expect(page).to have_css(...) # check for whatever visible change on the page indicates the action triggered by send_keys has completed
  end.to change { current_user.reload.messages.count }.by(1)
end

注意:这个测试对于特性测试来说也很简单。在功能测试中存在多个期望是可以的,因为它实际上是为了测试整个用户与应用程序特定功能的交互。您可能希望将此测试与应用程序同一部分的其他测试结合起来。

关于ruby-on-rails - Rspec期望更改计数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48501931/

相关文章:

ruby-on-rails - 使用 Capybara 将 GET 参数传递给 Controller

ruby-on-rails - Rails 3 Observer——希望学习如何为多个模型实现一个观察者

ruby-on-rails - 使用 Capistrano 部署时将静态文件保存在服务器中

ruby-on-rails - 使用 RSpec 测试 Controller 时如何调用 Rails 命名路由?

ruby - 使用 Capybara/Selenium/RSpec 抑制奇怪的输出

ruby-on-rails-3 - Rspec 头痛 : configuration advice appreciated

ruby-on-rails - 数组存储为字符串。如何将它转换回任何数组?

ruby-on-rails - rails : Sending PUT Request using curl/Postman to update an attribute

ruby-on-rails - Rspec 不能 stub where 或 find_by_,只能找到

google-chrome - Capybara、Selenium、 headless Chrome、Ubuntu Net::ReadTimeout