Q&A
解決したいこと
現在ポートフォリオ作成中のプログラミング入門者です。テストを書くのにRspecを使ってみようと考えたので、Rspecを使い、テストを作成しています。ですが、音声ファイルの検証テストを書く際にエラーが起こってしまいました。
エラー
Failures: 1) DictumUser test for DictumUser when user input invalid parameter when user is deleted gogaku is deleted too Failure/Error: expect(Gogaku.count).to eq 1 expected: 1 got: 0 (compared using ==) # ./spec/models/dictum_user_spec.rb:126:in `block (5 levels) in <top (required)>' 2) Gogaku test for gogaku gogaku should be valid Failure/Error: expect(gogaku).to be_valid expected #<Gogaku id: nil, subject: "English", body: "in trip", file: nil, answer: "none", dictum_user_id: nil, created_at: nil, updated_at: nil> to be valid, but got errors: Dictum user can't be blank # ./spec/models/gogaku_spec.rb:17:in `block (3 levels) in <main>' Finished in 0.31763 seconds (files took 1.52 seconds to load) 11 examples, 2 failures Failed examples: rspec ./spec/models/dictum_user_spec.rb:119 # DictumUser test for DictumUser when user input invalid parameter when user is deleted gogaku is deleted too rspec ./spec/models/gogaku_spec.rb:13 # Gogaku test for gogaku gogaku should be valid
該当するソースコード
#/spec/factories/dictum_users.rb FactoryBot.define do factory :dictum_user do sequence(:name) { |n| "user#{n}" } sequence(:email) { |n| "test#{n}@example.com" } password { "password" } password_confirmation { "password" } end #/spec/factories/gogakus.rb FactoryBot.define do factory :gogaku do subject {"English"} body {"in trip"} after(:build) do |gogaku| gogaku.file = fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'Night_Sea.mp3'), 'audio/mp3', :binary) end answer {"none"} association :dictum_user end end # spec/models/dictum_user_spec.rb require 'rails_helper' RSpec.describe DictumUser, type: :model do describe "test for DictumUser" do context "should be valid" do it "create instance accurately" do expect(user).to be_valid end end context "when user input invalid parameter" do context "when name which user input is empty" do user = FactoryBot.build(:dictum_user, name: "") it " regard the user as invalid" do expect(user).not_to be_valid end end context "when name which user input is too long" do user = FactoryBot.build(:dictum_user, name: "a"*51) it " regard the user as invalid" do expect(user).not_to be_valid end end context "when email which user input is empty" do user = FactoryBot.build(:dictum_user, email: "") it "regard the user as invalid" do expect(user).not_to be_valid end end context "when email which user input is invalid format" do user = FactoryBot.build(:dictum_user, email: "email.com") it "regard the user as invalid" do expect(user).not_to be_valid end end context "when email which user input is too long" do user = FactoryBot.build(:dictum_user, email: "a"*244+"@example.com") it "regard the user as invalid" do expect(user).not_to be_valid end end context "when password which user input is empty " do user = FactoryBot.build(:dictum_user, password: " "*6, password_confirmation: " "*6) it "regard the user as invalid" do expect(user).not_to be_valid end end context "when password which user input is too short" do user = FactoryBot.build(:dictum_user, password: "hoge", password_confirmation: "hoge") it "regard the user as invalid" do expect(user).not_to be_valid end end context "when email which user input isn`t unique" do user = FactoryBot.build(:dictum_user) it "regard the user as invalid" do user.save user2 = user.dup user2.email = user2.email.upcase user2.save expect(user2).not_to be_valid end end context "when user is deleted" do user = FactoryBot.build(:dictum_user) gogaku = FactoryBot.build(:gogaku, dictum_user: user) it "gogaku is deleted too" do expect(Gogaku.count).to eq 1 user.destroy expect(Gogaku.count).to eq 0 end end end end end #/spec/models/gogaku_spec.rb require 'rails_helper' RSpec.describe Gogaku, type: :model do describe "test for gogaku" do let(:dictum_user) { FactoryBot.build(:dictum_user) } let(:gogaku) { FactoryBot.build(:gogaku, dictum_user: dictum_user) } it "gogaku should be valid" do expect(gogaku).to be_valid end end end #gogaku.rb class Gogaku < ApplicationRecord belongs_to :dictum_user default_scope -> { order(created_at: :desc) } validates :subject,presence:true validates :body, presence:true has_one_attached :file validates :dictum_user_id, presence: true validates :file,presence:true validates :file,size: { less_than: 5.megabytes, message: "should be less than 5MB" } end #
自分で試したこと
https://gist.github.com/h-sakano/50092b1c17fe8ddc0bbe5382fb8587a4
https://qiita.com/h-sakano/items/fc297f91a7bafc0b4d6d
・最初にこの方たちの記事を参考にさせていただきました。ですが、私の場合、
# spec/factories/dictum_users.rb after(:build) do |gogaku| gogaku.file = fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'Night_Sea.mp3'), 'audio/mpeg', :binary) end
このように記述してもエラーが直りませんでした。
・次に
https://qiita.com/tatematsu-k/items/1cdd946cd38e69d16340
この方の記事を参考にさせていただきました。rails6.1.5を使っていたので以下を追及
#rails_helper.rb FactoryBot::SyntaxRunner.class_eval do include ActionDispatch::TestProcess include ActiveSupport::Testing::FileFixtures end
ですが、エラーが直りません。
・なぜか「when user is deleted gogaku is deleted too」の部分でDictum_userが空になっているというエラーが出ます。これはモデルでhas_manyの関係になっていることが原因かと考えられます(DictumUserが親Gogakuが子)。
https://qiita.com/takehanKosuke/items/ae324483e7f9451bf6a7
https://qiita.com/__kotaro_/items/adbc355bfb550b8b2150
https://qiita.com/johnslith/items/c0b2a9b8ce8770e5d317
こちらの方たちの記事を参考にさせていただき、関連付けが正しくできているか確認しました。恐らくできていると思いますが、なぜか上手く行きません。
その他
・ruby3.0.3 rails6.1.5 環境構築はDockerで行いました。wsl2のUbuntuを使っています。
・大幅に質問内容が変わったため、以前の質問を修正する形で投稿しています。
・また、推奨されていませんがマルチポストをしています
https://ja.stackoverflow.com/questions/87956/rspec%e3%81%a7%e9%9f%b3%e5%a3%b0%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e8%a8%ad%e5%ae%9a%e3%81%8c%e5%87%ba%e6%9d%a5%e3%81%9a-user-cant-be-blank%e3%81%8c%e8%a7%a3%e6%b6%88%e3%81%a7%e3%81%8d%e3%81%aa%e3%81%84
プログラミング入門者なので何かしら間違えた認識をしているかもしれません。何かしらアドバイスがあればよろしくお願いいたします。
追記
https://insyokuprogram.com/2021/08/08/%E3%80%90ruby-on-rails%E3%80%91to-be-valid-but-got-errors-user-cant-be-blank-%E3%80%90rspec%E3%80%91%E3%81%8C%E8%A7%A3%E6%B1%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E4%BB%B6/
こちらの方の記事を参考にさせていただき、buildと記述している部分をcreateに変更したところエラーが変化しました。
An error occurred while loading ./spec/models/dictum_user_spec.rb. Failure/Error: gogaku = FactoryBot.create(:gogaku, dictum_user: user) ActiveStorage::IntegrityError: ActiveStorage::IntegrityError # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/service/disk_service.rb:159:in `ensure_integrity_of' # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/service/disk_service.rb:22:in `block in upload' # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/service.rb:155:in `instrument' # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/service/disk_service.rb:20:in `upload' # /usr/local/bundle/gems/activestorage-6.1.5/app/models/active_storage/blob.rb:253:in `upload_without_unfurling' # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/attached/changes/create_one.rb:26:in `upload' # /usr/local/bundle/gems/activestorage-6.1.5/lib/active_storage/attached/model.rb:77:in `block in has_one_attached' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/evaluation.rb:18:in `create' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy/create.rb:12:in `block in result' # <internal:kernel>:90:in `tap' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy/create.rb:9:in `result' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory.rb:43:in `run' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory_runner.rb:29:in `block in run' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory_runner.rb:28:in `run' # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy_syntax_method_registrar.rb:28:in `block in define_singular_strategy_method' # ./spec/models/dictum_user_spec.rb:117:in `block (4 levels) in <top (required)>' # ./spec/models/dictum_user_spec.rb:114:in `block (3 levels) in <top (required)>' # ./spec/models/dictum_user_spec.rb:27:in `block (2 levels) in <top (required)>' # ./spec/models/dictum_user_spec.rb:5:in `block in <top (required)>' # ./spec/models/dictum_user_spec.rb:3:in `<top (required)>' Finished in 0.00009 seconds (files took 1.79 seconds to load) 0 examples, 0 failures, 1 error occurred outside of examples
現在ここでデバッグ中です。
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。