如何在Rails的测试中更新灯具?

时间:2009-09-09 22:51:56

标签: ruby-on-rails unit-testing fixtures

下面我列出了一些来自简单Rails应用程序的代码。下面列出的测试在最后一行失败,因为在此测试中PostController的更新操作中帖子的 updated_at 字段未更改。为什么呢?

这种行为在我看来有点奇怪,因为Post模型中包含标准时间戳,本地服务器上的实时测试表明该字段在从更新操作返回并且第一次断言完成后实际更新因此它显示更新操作正常。

如何以上述方式制作灯具可更新

# app/controllers/post_controller.rb
def update
  @post = Post.find(params[:id])
  if @post.update_attributes(params[:post])
    redirect_to @post     # Update went ok!
  else
    render :action => "edit"
  end
end

# test/functional/post_controller_test.rb
test "should update post" do
  before = Time.now
  put :update, :id => posts(:one).id, :post => { :content => "anothercontent" }
  after = Time.now

  assert_redirected_to post_path(posts(:one).id)     # ok
  assert posts(:one).updated_at.between?(before, after), "Not updated!?" # failed
end

# test/fixtures/posts.yml
one:
  content: First post

2 个答案:

答案 0 :(得分:4)

posts(:one)

这意味着“在posts.yml中获取名为”的一个“一个”。在测试期间永远不会改变,除非一些非常奇怪和破坏性的代码在理智的测试中无处可去。

您要做的是检查控制器正在分配的对象。

post = assigns(:post)
assert post.updated_at.between?(before, after)

答案 1 :(得分:1)

如果您使用的是shoulda(http://www.thoughtbot.com/projects/shoulda/),请注意这一点:

context "on PUT to :update" do
    setup do 
        @start_time = Time.now
        @post = posts(:one)
        put :update, :id => @post.id, :post => { :content => "anothercontent" } 
    end
    should_assign_to :post
    should "update the time" do
        @post.updated_at.between?(@start_time, Time.now)
    end
end

应该很棒。