if task_list.update_attributes(name: params[:task_list][:name])
respond_with task_list, status: :ok, location: task_list
else
respond_with task_list.errors, status: :unprocessable_entity
end
end
end[/code]
i testy:
[code=ruby]require ‘spec_helper’
describe TaskListsController do
include Devise::TestHelpers
before :all do @user = Factory :user @other_user = Factory :user, username: ‘batman’, email: ‘bat@man.com’ @task_list = Factory :task_list, user_id: @user.id @task = Factory :task, user_id: @user.id, task_list_id: @task_list.id
end
before :each do
sign_in :user, @user
end
describe “PUT update” do
it “should update task list” do
put :update, id: 1, format: :json, task_list: { name: “Let’s change name!” }
puts response.body
# response.body.should == …
end
end
end[/code]
response.body jest puste. niemal taki sam kod przy akcjach (i testach) index, show, create działa. update nie wyświetla żadnych błędów a jednak nie zwraca zmienionego obiektu.
response body jest puste bo domyślnie rspec nie renderuje widoków w testach kontrolera
Robiąc testy kontrolera powinieneś co najwyżej sprawdzić czy wykonuje odpowedni render, bo do tego sprowadza się z grubsza rola kontrolera
Chcąc sprawdzić czy wywołanie akcji “x” w kontrolerze dało w odpowiedzi xml, json lub innej formie “a”,“b”,“c” robisz testy integracyjne, troszkę inny zestaw narzędzi
Był niedawno railscast rspec/capybara
Jest też brzydsze rozwiązanie dopisz w teście
describe TaskListsController do
render_views
wymusisz “renderowanie” widoków w teście kontrolera ale dostajesz wtedy w response.body zwykły String i tracisz wiele zabawek capybary.
Poza tym łączysz test kontrolera i widoku w teście kontrolera a to tworzy mały bałagan
Wiem, że nie do końca tak powinno się pisać testy (chodzi mi o podział na integracyjne itd.), ale każda testowana przeze mnie akcja wymaga bycia zalogowanym. Niestety helper sign_in (z Devise::TestHelpers) działa tylko w testach kontrolerów (przynajmniej taką informację znalazłem na liście dyskusyjnej devise).