問題
統合テストを実行したら以下のエラーが生じた。
ERROR SiteLayoutTest#test_layout_links (0.22s)
Minitest::UnexpectedError:NoMethodError: undefined method `body' for nil:NilClass
response.body
^^^^^
test/integration/site_layout_test.rb:7:in `block in <class:SiteLayoutTest>'
test/integration/site_layout_test.rb:7
が指摘されている。
require "test_helper"
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
assert root_path
assert_template 'articles/index' # ここでエラーが発生
end
end
articlesコントローラのindexアクションのビューを描画しようとしてエラーが出ている。
responseオブジェクトのbodyプロパティを呼び出そうとするとnilが返ってきている。
実際の画面ではindex.htmlが問題なく表示されているのに、なぜテストだとnilになるのか?
試しにエラーが出ている箇所だけコメントアウトして、assert root_path
だけでもエラーが生じるか確認してみた。
その結果、assert root_path
ではエラーが生じなかった。
このことから、root_path
にHTTPリクエストを送るところでは問題が出ていないが、正しくビューが返されていないのが問題だとわかった。
原因
responseがnilになっている原因は?
→ そもそもHTTPリクエスト(GET)が送られていなかったから
試したこと
/articles
にアクセスした場合はエラーにならなかった。どっちも同じarticles#index
を指定しているのになんでだ?
require "test_helper"
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get '/articles'
assert_response :success
end
end
Rails.application.routes.draw do
root "articles#index"
get "/signup", to: "users#new"
get "/login", to: "sessions#new"
post "/login", to: "sessions#create"
delete "/logout", to: "sessions#destroy"
resources :users
resources :articles
get '/articles', to: 'articles#index'
end
解決した方法
require "test_helper"
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
assert root_path
get root_path # これを追加
assert_template 'articles/index'
end
end
assert root_path
はroot_pathが存在することを確認しているだけで、root_pathにリクエストを送っているわけではなかった。
assert root_path
でリクエストを送ったつもりになっていた。assert
をちゃんとわかっていなかったのが誤りの原因だった。
get root_path
でGETリクエストを送ったらresponse
にデータが入っていることがbinding.pry
で確認できた。