#はじめに
RSpec '4.0.1'
rails '6.0.3.2'
※訳あって今回はFactoryBotは使用していません
#エラー
controllerのテストであるリクエストテストを実装中にどハマり
createアクションに対するテストで
- modelのレコードが1つ増加する(←これはすぐ出来た)
- ユーザー詳細ページ(show.html.erb)にリダイレクトされる(←ここで4時間くらい試行錯誤)
before do
@user = User.create(name: "abc", email: "abc@abc.com")
@user_params = {:name =>"abc", :email => "abc@abc.com"}
@un_user_params = {:name =>"", :email => "abc@abc.com"}
end
describe 'POST /create' do
context 'Userモデルへの保存に成功したとき' do
it 'Userモデルのレコードが1つ増加する' do
expect {
post users_path, params: { user: @user_params }}
.to change(User, :count).by(1)
end
it 'ユーザー詳細ページ(show)にリダイレクトされる' do
post users_path, params: { user: @user_params }
expect(response).to redirect_to user_path(`??????`)
end
end
この最後のuser_path(:id)
の指定の仕方がわからなかった
解決方法だけ知りたい方は飛ばしてみて下さい
以下、色々試してみたコード達
##user = User.create(@user_params)
paramsで1回データが保存されるからそりゃ保存したuserと別でcreateしたuserじゃidが合わない
(テストしまくったのでidが772とかいう異次元)
Failure/Error: expect(response).to redirect_to user_path(user.id)
Expected response to be a redirect to <http://www.example.com/users/772> but was a redirect to <http://www.example.com/users/771>.
Expected "http://www.example.com/users/772" to be === "http://www.example.com/users/771".
# ./spec/requests/users_spec.rb:82:in `block (4 levels) in <main>'
##@user_params = {:id =>1, :name =>"abc", :email => "abc@abc.com"}
今度は@user_paramsにidを設定しちゃって保存すればid一致するでしょ!
と思ったけど保存された時点で別IDに被りで置き換わるからまたまた一致せず・・・・
Failure/Error: expect(response).to redirect_to user_path(@user_params[:id])
Expected response to be a redirect to <http://www.example.com/users/1> but was a redirect to <http://www.example.com/users/790>.
Expected "http://www.example.com/users/1" to be === "http://www.example.com/users/790".
# ./spec/requests/users_spec.rb:81:in `block (4 levels) in <main>'
##expect(response).to redirect_to user_path(params[:id])
もうわけわかんないからどっかから奇跡的にparamsが拾って来てくれないかなと思ったけどもちろんダメ
Failure/Error: expect(response).to redirect_to user_path(params[:id])
NameError:
undefined local variable or method `params' for #<RSpec::ExampleGroups::Users::POSTCreate::User:0x00007fbc3168cbb8>
# ./spec/requests/users_spec.rb:81:in `block (4 levels) in <main>'
##expect(response).to redirect_to user_path(:params[:id])
もちろんむり
Failure/Error: expect(response).to redirect_to user_path(:params[:id])
TypeError:
no implicit conversion of Symbol into Integer
# ./spec/requests/users_spec.rb:81:in `[]'
# ./spec/requests/users_spec.rb:81:in `block (4 levels) in <main>'
##expect(response).to redirect_to user_path(params: [:id])
もちろんむり
Failure/Error: expect(response).to redirect_to user_path(params: [:id])
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"users"}, missing required keys: [:id]
# ./spec/requests/users_spec.rb:81:in `block (4 levels) in <main>'
##expect(response).to redirect_to user_path
もはやidを指定しない
そりゃむり
Failure/Error: expect(response).to redirect_to user_path
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"users"}, missing required keys: [:id]
# ./spec/requests/users_spec.rb:81:in `block (4 levels) in <main>'
リファレンスとか色々読みあさってもまったくどうすればいいかわからず
上に書いたコードをたぶん同じこと何周も試した・・・
#解決策
最終的には下記のコードで通った
新しくデータを保存 = Userモデルの中では一番最後のIDを割り振られる
つまりuser.last
としてあげると新しく保存されたレコードを指定できる・・・
it 'ユーザー詳細ページ(show)にリダイレクトされる' do
post users_path, params: { user: @user_params }
expect(response).to redirect_to user_path(User.last)
end
なぜわかったかというとgithubの変更履歴にのってた
いじる前の最初の記述(自動的に生成された)はこれだったみたい
なんてこっちゃ
- it 'redirects to the created user' do
- post users_url, params: { user: valid_attributes }
- expect(response).to redirect_to(user_url(User.last))
+ it 'ユーザー詳細ページ(show)にリダイレクトされる' do
+ post users_path, params: { user: @user_params }
+ expect(response).to redirect_to user_path(User.last)