How do I make fixtures updatable in Rails tests?
Below I have listed some code from a simple Rails application. The test below fails on the last line because the updated_at field of the message is not changed in the PostController update action in that test. Why?
I think this behavior is a bit odd because the standard standard labels are included in the Post model, live testing on the local server shows that this field is indeed updated after returning from the update action, and the first statement is executed, thus it shows that the action updates took place approx.
How can I update the fixtures in the above value?
# 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
source to share
posts(:one)
This means, "Get a fixture named" one "in posts.yml. This will never change during the test, except for some extremely weird and destructive code that does not exist in reasonable tests.
What you want to do is check the object assigned by the controller.
post = assigns(:post) assert post.updated_at.between?(before, after)
source to share
On the side of the note, if you used shoulda ( http://www.thoughtbot.com/projects/shoulda/ ) it would look like this:
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
The smile is wonderful.
source to share