سؤال

I am trying to test my controller. Everything was doing fine until I tried to test the update action.

This is my Test

require 'test_helper'

class BooksControllerTest < ActionController::TestCase
    test "should not update a book without any parameter" do
        assert_raises ActionController::ParameterMissing do 
            put :update, nil, session_dummy
        end
    end
end

This is my Controller

class BooksController < ApplicationController

    (...)

    def update
        params = book_params
        @book = Book.find(params[:id])

        if @book.update(params)
            redirect_to @book
        else
            render 'edit'
        end
    end

    (...)

    def book_params
        params.require(:book).permit(:url, :title, :price_initial, :price_current, :isbn, :bought, :read, :author, :user_id)
    end
end

My application's routes for the books controller follows:

    books GET    /books(.:format)                      books#index
          POST   /books(.:format)                      books#create
 new_book GET    /books/new(.:format)                  books#new
edit_book GET    /books/:id/edit(.:format)             books#edit
     book GET    /books/:id(.:format)                  books#show
          PATCH  /books/:id(.:format)                  books#update
          PUT    /books/:id(.:format)                  books#update
          DELETE /books/:id(.:format)                  books#destroy

And when I run rake test I get:

1) Failure:
BooksControllerTest#test_should_not_update_a_book_without_any_parameter [/Users/acavalca/Sites/book-list/test/controllers/books_controller_test.rb:69]:
[ActionController::ParameterMissing] exception expected, not
Class: <ActionController::UrlGenerationError>
Message: <"No route matches {:action=>\"update\", :controller=>\"books\"}">
---Backtrace---
test/controllers/books_controller_test.rb:70:in `block (2 levels) in <class:BooksControllerTest>'
test/controllers/books_controller_test.rb:69:in `block in <class:BooksControllerTest>'
---------------

So, what am I missing here? I've done a search on this but could not find anything. Only a few RSpec examples, that seem quite similar to what I've done, still I have no clue.

هل كانت مفيدة؟

المحلول

You need to at least send it the ID of a Book. Notice that the route looks like this:

PUT    /books/:id(.:format)                  books#update

That :id part is an integral part of the URL. This means that trying to do a PUT to /books/ doesn't make sense, but doing one to /books/1 is a valid URL, even if ID 1 doesn't match any record in the database.

You will have to at least send a parameter for the :id to make this test work.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top