使用rspec测试页面视图计数器

时间:2012-09-22 08:08:34

标签: 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) >'

这是我的test.log:

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或我编写测试的方式。

1 个答案:

答案 0 :(得分:2)

如你所知,

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

比较块执行前后story.counter的值。当您的控制器加载并修改故事时,这是一个完全独立的ruby对象(恰好引用数据库中的同一行):规范代码中的story对象不知道对数据库所做的更改并保持相同(现在陈旧)的数据。

为了让您的规范通过,您可以检查story.reload.counter是否正在发生变化。