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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

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

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

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

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

Q&A

解決済

1回答

574閲覧

RSpecにおいてcontroller側での関連づけされたmodelの取得箇所でnill classになってしまう。

TakagiMarin

総合スコア13

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

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

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

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

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

0グッド

0クリップ

投稿2021/09/11 15:20

編集2021/09/11 22:58

前提・実現したいこと

ユーザー情報の登録でブロック企業の登録、更新機能を作っています。
最終的にはこの登録、更新のテストを追加したいのですが、
その前段階としてフォームの表示部分のテストを実装したいです。

発生している問題・エラーメッセージ

RSpecでテストを書いているのですが、コントローラ側でcurrent_user
関連づけされたmodelを取得する部分でnill classとなってしまっています。
エラーメッセージは以下の通りです。

Failure/Error: @user_blocking_corporation = current_user.user_profile.user_blocking_corporation || UserBlockingCorporation.new(user_profile_id: current_user.user_profile.id) NoMethodError: undefined method `user_blocking_corporation' for nil:NilClass

該当のソースコード

Auth0を使ってログイン機能を実装しているため、モックを使ってログインしています。
この時の情報をsessionに格納し、これを基にcurrent_userを取得しています。

ruby

1#spec/requests/users_configurations_controllers_spec.rb 2describe Users::ConfigurationsController, type: :request do 3 describe "Get /users/configurations" do 4 let(:user) { create(:user) } 5 let(:user_profile) { create(:user_profile, user: user) } 6 7 before do 8 OmniAuth.config.test_mode = true 9 OmniAuth.config.mock_auth[:auth0] = nil 10 11 ...中略 12 13   OmniAuth.config.mock_auth[:auth0] = OmniAuth::AuthHash.new(opts) 14 Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:auth0] 15 16 get '/auth/auth0/callback?code=vihipkGaumc5IVgs' 17 end 18 19 it 'ブロック企業が未設定の場合inputが空表示されている' do 20 get '/users/configurations' 21 expect(find('#user_profile_user_blocking_corporation_attributes_corporation_id').empty?).to eq: true 22 expect(find('#js-form__corporation-search').value).to eq: '' 23 end 24

FactoryBotは以下になります。

ruby

1#spec/factories/users.rb 2FactoryBot.define do 3 factory :user do 4 sequence(:email) { |n| "user#{n}@rxample.com" } 5 provider { 'auth0' } 6 uid { "auth0|123456789123456789123" } 7 end 8end 9 10#spec/factories/user_profiles.rb 11FactoryBot.define do 12 factory :user_profile do 13 association :user, factory: :user 14 sequence(:name) { |n| "テストユーザー#{n}" } 15 sequence(:name_ruby) { |n| "てすとゆーざー#{n}" } 16 sex { 'male' } 17 telephone { "090#{format("%0#8d", SecureRandom.random_number(10**8))}" } 18 birth_year { Date.today.ago(20.years).year } 19 birth_month { Date.today.mon } 20 birth_day { Date.today.mday } 21 end 22end

ruby

1#controllers/users/configurations_controller.rb 2class Users::ConfigurationsController < ApplicationController 3 def show 4 @user_blocking_corporation = current_user.user_profile.user_blocking_corporation || UserBlockingCorporation.new(user_profile_id: current_user.user_profile.id) 5 end 6end

ruby

1#models/user.rb 2class User < ApplicationRecord 3 has_one :user_profile 4...省略 5 6#models/user_profile.rb 7class UserProfile < ApplicationRecord 8 belongs_to :user 9 has_one :user_blocking_corporation 10...省略 11 12#models/user_blocking_corporation.rb 13class UserBlockingCorporation < ApplicationRecord 14 belongs_to :user_profile 15...省略

試したこと

最初ログインが上手くいかずにcurrent_userが取得できず、
user_profileがnill classになっていました。
現状ここはクリアし、次のuser_blocking_corporationがnill classとなっています。
なので、おそらくuser_profileが上手く取得できていないと思われます。

通常のviewの表示では期待通りの動きをしていますので、
おそらくテストが間違っているのではないかと思います。
よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ruby 2.7.3p183
Ruby on Rails6
rspec-rails 5.0.1

追記

以下の様に状況を確認してみました。

ruby

1#_spec.rb 2#こちらのテストは通りました 3subject { user.id } 4it {is_expected.to eq(user_profile.user_id)} 5 6#こちらは通りません 7subject { user.user_profile } 8it {is_expected.to eq(user_profile)} 9 10Failure/Error: it {is_expected.to eq(user_profile)} 11 12expected: #<UserProfile id: 15, user_id: 95, name: "テストユーザー", birth_year: 2001, birth_month... updated_at: "2021-09-12 07:52:49.000000000 +0900"> 13got: nil

ruby

1#show.html.erb 2#こちらはきちんと表示されます 3<%= current_user.user_profile.id %>

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

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

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

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

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

guest

回答1

0

自己解決

letではなくlet!を使用する!
間違いはここでした。
それぞれの挙動の違いについてあまり理解をしていなかったのですが、
letは遅延で定数が使われた段階で初めて作られるもの。
let!は逆にテストブロック実行前に作られるもの。
なので前者はsubject{user.user_profile}の段階ではまだuser_profileが作られていなかったということでした。
お考えいただいた皆様、ありがとうございました!

投稿2021/09/11 23:17

TakagiMarin

総合スコア13

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問