简体   繁体   中英

Rails Controller Testing: ActionController::UrlGenerationError: No route matches

I'm teaching myself to write controller tests and am getting this getting this error:

ERROR["test_should_update_post", PostsControllerTest, 2015-10-11 12:12:31 -0400]
 test_should_update_post#PostsControllerTest (1444579951.69s)
ActionController::UrlGenerationError:         ActionController::UrlGenerationError: No route matches {:action=>"update", :controller=>"posts", :post=>{:title=>"My Post", :body=>"Updated Ipsum"}}
            test/controllers/posts_controller_test.rb:51:in `block (2 levels) in <class:PostsControllerTest>'
            test/controllers/posts_controller_test.rb:50:in `block in <class:PostsControllerTest>’

This is my test:

test "should update post" do 
  assert_difference('Post.count') do 
    put :update, post: {title: 'My Post', body: 'Updated Ipsum'}
  end

  assert_redirected_to post_path(assigns(:post))
end

this is my yaml:

entry_one:
  title: "Foobar"
  body: "Ipsum This"

entry_two:
  title: "Barfoo"
  body: "This Ipsum"

and this is my controller:

def update
    @post = Post.find(params[:id])

    if @post.update(post_params)
        redirect_to @post, notice: 'Event updated successfully'
    else
        render :edit
    end
end

Can you point me towards the problem I need to solve?

I can tell from the error and the line count that it's something to do with the lines: assert_difference('Post.count') do and put :update, post: {title: 'My Post', body: 'Updated Ipsum'}

您需要将id传递给update操作:

put :update, id: <THE ID HERE>, post: {title: 'My Post', body: 'Updated Ipsum'}

According to your update action in your controller, you need to pass an id of the post in your params .

So, in your test, build your params hash like this:

let(:update_query_parameters) { { post: { title: 'My Post', body: 'Updated Ipsum' }, id: post.id } }

Then, use update_query_parameters to pass as params for your put :update method:

test "should update post" do
  assert_difference('Post.count') do
    put :update, update_query_parameters
  end

  assert_redirected_to post_path(assigns(:post))
end

Thanks to two the commenters above, I was able to understand the problem I needed to solve: That I need to pass an id in my update test.

I'd already done this in a similar edit test for the same app, i knew exactly what to try.

I'd previously used a setup method in my test to pass my yaml shared above into my tests:

def setup
   @post = posts(:entry_one)
end

With this method I can pass @post.id into my update test and get it to pass as such:

test "should update post" do 
  assert_no_difference('Post.count') do 
    put :update, id: @post.id, post: {title: 'My Post', body: 'Updated Ipsum'}
  end

  assert_redirected_to post_path(assigns(:post))
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM