【问题标题】:How to make fixtures updateable in Rails' tests?如何在 Rails 的测试中使夹具可更新?
【发布时间】:2009-09-09 22:51:55
【问题描述】:

下面我列出了一些来自简单 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

【问题讨论】:

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


    【解决方案1】:
    posts(:one)
    

    这意味着“在posts.yml 中获取名为“:one”的fixture。这在测试期间永远不会改变,除非一些极其奇怪和破坏性的代码在正常测试中没有位置。

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

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

    【讨论】:

    • 非常感谢,这就是我正在寻找的解决方案!
    【解决方案2】:

    附带说明,如果您使用的是 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
    

    应该很棒。

    【讨论】:

    • 确实如此。应该是很棒的东西。
    猜你喜欢
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2021-02-18
    相关资源
    最近更新 更多