質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

782閲覧

rails controllerの単体テストでの設定

ryuuzu

総合スコア30

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/04/30 12:52

スクールの課題でメルカリのようなフリマアプリを作成しております。

現在単体テストを作成中です。

商品テーブルのモデルテストはrspecとfactorybotを使用して以下のように作成しました。
↓商品テーブルのitemテーブルのfactory

FactoryBot.define do factory :item do item_images {[build(:item_image)]} user_id {"1"} name {"柑橘"} explanation {"酸っぱい"} category_id {"365"} brand {"あきひめ"} condition_id {"1"} delivery_charge_id {"1"} shipping_origin_id {"24"} sending_days_id {"2"} price {"3000"} end end

商品テーブルのitem_iamges(商品の画像)のfactory

FactoryBot.define do factory :item_image do image { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec/factories/test.jpg')) } end end

この状態で以下のモデルテストのコードを組んだところ、テストは成功しました。

require 'rails_helper' describe Item do describe '#create' do let(:image_path) { File.join(Rails.root, 'spec/factories/test.jpg') } let(:image) { Rack::Test::UploadedFile.new(image_path) } it "商品出品のバリデーションが機能しているか?" do item = build(:item) expect(item).to be_valid end end end

次にコントローラのコードです。

require 'rails_helper' describe ItemsController, type: :controller do describe 'GET #new' do #ログインしている状態にする let(:user) { create(:user) } before do login user end it "1.new.html.hamlに遷移する" do get :new expect(response).to render_template :new end end describe 'POST #create' do subject { post :create, params } let(:user) { create(:user) } let(:params) do (build(:item)) end context 'ログインしている場合' do before do login user end context '保存に成功した場合' do it '2.itemを保存すること' do item = build(:item) expect{post :create, params: params}.to change(Item, :count).by(1) end it '3.入力が不適切の場合、:newに飛ぶ' do expect(post :create).to redirect_to(new_item_path) end end end end #ログインしていない時の処理 it "4.ログインしていないとnew_user_session_pathに遷移する" do get :new expect(response).to redirect_to(new_user_session_path) end end

こちらでテストをすると2と3が失敗します。
3は2が失敗している時点で失敗なのはわかるのですが2が失敗に終わる理由がわかりません。

エラーメッセージを見ると
undefined method `symbolize_keys' for #Item:0x00007fdc19916c50
と表示されていました。

長くなってしまいましたが、質問としては
①`symbolize_keys'とはどの部分で出てきたものなのでしょうか?
②外部キーが原因という理解でよろしいのでしょうか?
③外部キーとなると怪しいのはuserがitem_imagesかと思い、binding.pryをおいてparamsを調べてみたところ、
paramsの中にitem-imagesがありませんでした。

id: nil, name: "柑橘", likes: 0, category_id: 365, user_id: 1, price: 3000, explanation: "酸っぱい", brand: "あきひめ", created_at: nil, updated_at: nil, transaction_status: 1, sending_days_id: 2, shipping_origin_id: 24, delivery_charge_id: 1, condition_id: 1>

モデルのときは入れれていたのにコントローラでは認識されていないということなのでしょうか?

よろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

symbolize_keys というmethodの正確な機能はわかりませんが、命名から想像するに
{"name" => "Satou" } を { name: "Satou" } に変換しているのでは、と思います。
このエラーが出るのは
post :create, params: params の params が Itemのインスタンスだからです。
params.attributes にしてみてください

投稿2020/04/30 13:15

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryuuzu

2020/04/30 14:04

回答ありがとうございます。 expect{post :create, params: params}.to change(Item, :count).by(1)の部分を expect{post :create, params: params.attributes}.to change(Item, :count).by(1)とした所 param is missing or the value is empty: itemと表示されました。 これはitem_imageカラムが取得できていないということなのでしょうか?
winterboum

2020/04/30 22:20

controller がないので想像ですが params: { item: params.attributes} かな
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問