ruby-on-rails - 使用 rspec 测试页面浏览计数器

标签 ruby-on-rails ruby-on-rails-3 rspec

我在我的帖子模型中添加了一个非常简单的计数器。每当有人打开帖子时,它都会将相应字段 :counter 更新 1。

  def show
    @story = Story.find(params[:id])
    @comment = @story.comments.build
    @comments = @story.comments.arrange(order: :created_at)

    @story.increment!(:counter) # ---Here---

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @story }
    end
  end

实际上,我检查了数据库,这东西正在工作。但我的测试失败了:

it "raise the counter by one when visiting a page" do
  story = FactoryGirl.create(:story)
  expect {
    visit story_url(story)
    }.to change { story.counter }.by(1)
end

它显示:

1) Stories raise the counter by one when visiting a page
  Failure/Error: expect {
    result should have been changed by 1, but was changed by 0
    # ./spec/requests/stories_spec.rb:8:in `block (2 levels) in <top (required) >'

这是我的测试日志:

Started POST "/stories" for 127.0.0.1 at 2012-09-22 11:31:32 +0330
Processing by StoriesController#create as HTML
  Parameters: {"utf8"=>"✓", "story"=>{"title"=>"sfomqd8s2r", "content"=>"Beatae voluptatibus quia cumque voluptate. Beatae sed aut sit. Fugiat deleniti et vitae accusantium blanditiis. Consequatur at itaque temporibus autem. Quo beatae delectus minus porro et.", "tag_names"=>""}, "commit"=>"submit"}
   (0.1ms)  SELECT MIN("tags"."stories_count") AS min_id FROM "tags" 
   (0.1ms)  SELECT MAX("tags"."stories_count") AS max_id FROM "tags" 
  Tag Load (0.1ms)  SELECT name, stories_count FROM "tags" ORDER BY name asc
   (0.1ms)  SAVEPOINT active_record_1
  SQL (1.5ms)  INSERT INTO "stories" ("comments_count", "content", "counter", "created_at", "publish_date", "slug", "title", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)  [["comments_count", 0], ["content", "Beatae voluptatibus quia cumque voluptate. Beatae sed aut sit. Fugiat deleniti et vitae accusantium blanditiis. Consequatur at itaque temporibus autem. Quo beatae delectus minus porro et."], ["counter", 0], ["created_at", Sat, 22 Sep 2012 11:31:32 IRST +03:30], ["publish_date", nil], ["slug", nil], ["title", "sfomqd8s2r"], ["updated_at", Sat, 22 Sep 2012 11:31:32 IRST +03:30], ["user_id", nil]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
Redirected to http://www.example.com/stories/2
Completed 302 Found in 18ms (ActiveRecord: 1.9ms)


Started GET "/stories/2" for 127.0.0.1 at 2012-09-22 11:31:32 +0330
Processing by StoriesController#show as HTML
  Parameters: {"id"=>"2"}
   (0.1ms)  SELECT MIN("tags"."stories_count") AS min_id FROM "tags" 
   (0.1ms)  SELECT MAX("tags"."stories_count") AS max_id FROM "tags" 
  Tag Load (0.1ms)  SELECT name, stories_count FROM "tags" ORDER BY name asc
  Story Load (0.1ms)  SELECT "stories".* FROM "stories" WHERE "stories"."id" = ? LIMIT 1  [["id", "2"]]
  CACHE (0.0ms)  SELECT "stories".* FROM "stories" WHERE "stories"."id" = ? LIMIT 1  [["id", "2"]]
  Comment Load (0.2ms)  SELECT "comments".* FROM "comments" WHERE "comments"."story_id" = 2 ORDER BY (case when comments.ancestry is null then 0 else 1 end), comments.ancestry, created_at
  SQL (0.3ms)  UPDATE "stories" SET "counter" = 1 WHERE "stories"."id" = 2
  Tag Load (0.2ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."story_id" = 2
  Rendered stories/_story_operation.html.erb (3.5ms)
  Rendered stories/_story.html.erb (5.4ms)
  Rendered comments/_form.html.erb (7.1ms)
Completed 200 OK in 34ms (Views: 18.1ms | ActiveRecord: 1.1ms | Solr: 0.0ms)
   (0.7ms)  rollback transaction

我不明白发生了什么。也许这与 Capybara 或我编写测试的方式有关。

最佳答案

如你所知,

expect {
  visit story_url(story)
}.to change { story.counter }.by(1)

比较 block 执行前后story.counter的值。当您的 Controller 加载并修改故事时,这是一个完全独立的 ruby​​ 对象(恰好引用数据库中的同一行):规范代码中的 story 对象不知道所做的更改到数据库并保存相同(现已过时)的数据。

要让您的规范通过,您可以检查 story.reload.counter 是否正在更改。

关于ruby-on-rails - 使用 rspec 测试页面浏览计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12542026/

相关文章:

ruby-on-rails - 顺便说一下,我是一名学生,如何在汉堡菜单中的 React on Rails 中添加注销

ruby-on-rails - 在 postgres heroku rails 3 应用程序上获取类名?

testing - 在 MSpec 中 stub 静态方法

ruby - 在这种情况下我将如何使用 VCR(使用 WebMock)?

ruby-on-rails - 使用 Rspec 的 Rails 5 邮件程序预览

ruby-on-rails - Rails 4 考勤系统

javascript - 用 jQuery 实现 Prototype 风格的类结构

ruby-on-rails - 如何正确注册和访问 OAuth2 的 Office 365 Graph API(使用来自 Ruby 的 omniauth)?

ruby-on-rails - 获取特定工作日的最接近日期

ruby-on-rails - Rails 3 引擎和代码在开发模式下重新加载