Как сделать светильники обновляемыми в тестах Rails? - PullRequest
2 голосов
/ 10 сентября 2009

Ниже я перечислил некоторый код из простого приложения Rails. Приведенный ниже тест завершается неудачей в последней строке, поскольку поле updated_at сообщения не изменяется в рамках действия обновления PostController в этом тесте. Почему?

Это поведение кажется мне немного странным, поскольку стандартные метки времени включены в модель 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 ]

4 голосов
/ 10 сентября 2009
posts(:one)

Это означает «получить прибор с именем»: one »в posts.yml. Это никогда не изменится во время теста, за исключением некоторого чрезвычайно странного и разрушительного кода, который не имеет места в нормальных тестах.

То, что вы хотите сделать, это проверить объект, который назначает контроллер.

post = assigns(:post)
assert post.updated_at.between?(before, after)
1 голос
/ 10 сентября 2009

На боковой ноте, если вы используете musta (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

Стоит круто.

...