前提・実現したいこと
ruby on railsのdeviseを使ってウィザード形式のユーザー登録の実装をしています。
複数モデルの情報をfields_forを使いながら画面遷移とともに入力し、ユーザー登録機能の実装はできるようになりましたが、Rspecのコントローラーテストで、fields_forを使って情報入力した部分のテストが通過しません。
テーブルは三種類あり、ユーザー情報、住所、カード情報のテーブルで分けており、
3ページ目でユーザー情報の一部と住所の入力をする欄を設けており、4ページ目でカード情報の入力をするページを設けております。
fields_forを使い実装した住所とカード情報のバリデーションチェックを単体テストで通過するように記述したく、投稿させていただきました。
調べても解決できず、お手上げ状態です。どうぞよろしくお願いします。
発生している問題・エラーメッセージ
Failures: 1) SignupController validates_step3 valid data redirect to step4 Failure/Error: expect(response).to render_template :step4 expecting <"step4"> but rendering with <["signup/step3", "layouts/application"]> # ./spec/controllers/signup_controller_spec.rb:185:in `block (4 levels) in <top (required)>' 2) SignupController create valid data redirect to done Failure/Error: expect(response).to render_template :done expecting <"done"> but rendering with <["signup/step1", "layouts/application"]> # ./spec/controllers/signup_controller_spec.rb:285:in `block (4 levels) in <top (required)>' Finished in 0.80791 seconds (files took 4.71 seconds to load) 59 examples, 2 failures, 1 pending Failed examples: rspec ./spec/controllers/signup_controller_spec.rb:183 # SignupController validates_step3 valid data redirect to step4 rspec ./spec/controllers/signup_controller_spec.rb:283 # SignupController create valid data redirect to done
バリデーションが通らない情報だともう一度前画面に戻って入力させるような仕様ですが、
テストでバリデーションを通る情報の記述方法がわからず、前の画面にrenderされてしまうテスト結果となります。
該当のソースコード
signup_controller.rb
class SignupController < ApplicationController before_action :validates_step1, only: :step2 before_action :validates_step2, only: :step3 before_action :validates_step3, only: :step4 def step1 @user = User.new # 新規インスタンス作成 end (略) def validates_step2 session[:cellphone] = user_params[:cellphone] #step2で入力した値をsessionに保存 @user = User.new( nickname: session[:nickname], # sessionに保存された値をインスタンスに渡す email: session[:email], password: session[:password], password_confirmation: session[:password_confirmation], cellphone: session[:cellphone], familyname: "sei", firstname: "mei", familyname_kana: "セイ", firstname_kana: "メイ", birthday: "2001-01-01" ) render '/signup/step2' unless @user.valid? end def step3 @user = User.new #新規インスタンス作成 @user.build_address #addressの入力を記述したビューを呼び出すアクションに記述 end def validates_step3 session[:familyname] = user_params[:familyname] #step3で入力した値をsessionに保存 session[:firstname] = user_params[:firstname] session[:familyname_kana] = user_params[:familyname_kana] session[:firstname_kana] = user_params[:firstname_kana] session[:phone] = user_params[:phone] session[:birthday] = user_params[:birthday] session[:address_attributes] = user_params[:address_attributes] @user = User.new( nickname: session[:nickname], #sessionに保存された値をインスタンスに渡す email: session[:email], password: session[:password], password_confirmation: session[:password_confirmation], familyname: session[:familyname], familyname_kana: session[:familyname_kana], firstname: session[:firstname], firstname_kana: session[:firstname_kana], cellphone: session[:cellphone], phone: session[:phone], birthday: session[:birthday] ) @user.build_address(session[:address_attributes]) render '/signup/step3' unless @user.valid? end def step4 @user = User.new #新規インスタンス作成 @user.build_card #cardの入力を記述したビューを呼び出すアクションに記述 end def create @user = User.new( email: session[:email], #sessionに保存された値をインスタンスに渡す password: session[:password], password_confirmation: session[:password_confirmation], nickname: session[:nickname], familyname: session[:familyname], firstname: session[:firstname], familyname_kana: session[:familyname_kana], firstname_kana: session[:firstname_kana], birthday: session[:birthday], cellphone: session[:cellphone], phone: session[:phone] ) @user.build_address(session[:address_attributes]) @user.build_card(user_params[:card_attributes]) if @user.save session[:id] = @user.id redirect_to done_signup_index_path else render '/signup/step1' end end def done sign_in User.find(session[:id]) unless user_signed_in? end private def user_params params.require(:user).permit( :email, :password, :password_confirmation, :nickname, :cellphone, :familyname, :firstname, :familyname_kana, :firstname_kana, :birthday, :phone, address_attributes: [:id, :postcode, :prefecture, :municipality, :address, :building], card_attributes: [:id, :card_number, :expiration_month, :expiration_year, :security_code] ) end end
signup_controller_spec.rb
require 'rails_helper' RSpec.describe SignupController, type: :controller do (略) describe "validates_step3" do context "valid data" do subject { user_params = attributes_for(:user) address = attributes_for(:address) post :step4, params: { user: user_params }, session: { name: 'sample_user', email: "aaa@gmail.com", password: "aaaa0000", password_confirmation: "aaaa0000", cellphone: '08011112222', familyname: 'sei', firstname: 'mei', familyname_kana: 'セイ', firstname_kana: 'メイ', birthday: '2000-01-01', user_id: 1, postcode: 1112222, prefecture: '東京都', municipality: '渋谷区', address: '1-1' } } it "redirect to step4" do subject expect(response).to render_template :step4 pending 'テストが失敗' end end end describe "create" do context "valid data" do subject { user_params = attributes_for(:user) address_params = attributes_for(:address) card_params = attributes_for(:card) post :create, params: { user: user_params, address_attributes: user_params, card_attributes: user_params }, session: { nickname: 'test_user', email: 'aaa@gmail.com', password: 'aaaa0000', password_confirmation: 'aaaa0000', cellphone: "08011112222", familyname: 'sei', firstname: 'mei', familyname_kana: 'セイ', firstname_kana: 'メイ', birthday: '2000-01-01', postcode: 1112222, prefecture: '東京都', municipality: '渋谷区', address: '1-1', card_number: '1111222233334444', expiration_month: '09', expiration_year: '21', security_code: '111' } } it "redirect to done" do subject expect(response).to render_template :done pending 'テストが失敗' end end end end
step3.html.rb
.main .information .information__head 住所入力 .information__main = form_for @user, url: step4_signup_index_path do |f| = f.text_field :familyname = f.text_field :firstname = f.text_field :familyname_kana = f.text_field :firstname_kana = f.fields_for :address do |b| = b.text_field :postcode, placeholder: '1234567' = b.text_field :prefecture, placeholder: '北海道' = b.text_field :municipality, placeholder: '例) 横浜市緑区' = b.text_field :address, placeholder: '例) 青山1−1−1' = b.text_field :building, placeholder: '例) 柳ビル103' = f.text_field :phone, placeholder: '例) 09012345678' = f.date_field :birthday, placeholder: '例) YYYY-MM-DD' = f.submit '次へ進む'
試したこと
fields_forで記述した部分の情報が送れていないのではという仮説ものと、
sessionで送るデータのパターンを変えてみましたが、そもそもどのように記述すればバリデーションが通るのかがわからず、お手上げ状態です。
あなたの回答
tips
プレビュー