我为我的帖子模型添加了一个非常简单的计数器。每当有人打开帖子时,它都会将相应的字段: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或我编写测试的方式。
答案 0 :(得分:2)
如你所知,
expect {
visit story_url(story)
}.to change { story.counter }.by(1)
比较块执行前后story.counter
的值。当您的控制器加载并修改故事时,这是一个完全独立的ruby对象(恰好引用数据库中的同一行):规范代码中的story
对象不知道对数据库所做的更改并保持相同(现在陈旧)的数据。
为了让您的规范通过,您可以检查story.reload.counter
是否正在发生变化。