LoginSignup
0
0

More than 3 years have passed since last update.

【RSpec】結合テストコードでエラーが出たり出なかったり〜安定しなかった謎が解けた〜

Last updated at Posted at 2021-02-17

本日の解決事件はこちら

結合テストコードを実行していると、コードをいじっていないのに突然エラーになったり

c21333dcd4ce40a563608db590a9ab21.png

もう一回やるとエラーが出なかったり
d0ada904790d314de8e795161ca00d08.png

立ち上がったブラウザを見てあまりにも動きが早いので
「こいつ、もしや動きが早すぎて自分が何やってるかわかってないんじゃないのか?」
と、勘ぐっていた。
ログインしてる時のブラウザの動きも目にも止まらぬ早さだし、ブラウザが更新された瞬間にはもうテキストが入力されている。

序.jpg

犯人はキング・クリムゾンでした!
なんて記事を書くのはなかなかどうかしてると思うのでちゃんと調べてみた。

エラーを読み解いてみる

Failures:

  1) Reviews レビューの編集と削除 レビューの編集画面に遷移したとき レビュータイトルにデータが入っていること
     Failure/Error: let(:party) { FactoryBot.create(:party) }

     ActiveRecord::RecordInvalid:
       バリデーションに失敗しました: パスワードは不正な値です

⬇️⬇️⬇️たまにこれも出る⬇️⬇️⬇️
  1) Reviews レビューの編集と削除 編集画面に遷移できる トップページに表示されている最新レビューから編集画面に遷移できる
     Failure/Error: @current_user_review = FactoryBot.create(:review, user: user)

     ActiveRecord::RecordInvalid:
       バリデーションに失敗しました: パスワードは不正な値です

FactoryBotで生成しているデータが悪さをしているのではないかと思いバリデーションを見直してみた。

spec/factories/reviews.rb

FactoryBot.define do

  factory :review do
    title       { Faker::JapaneseMedia::Doraemon.gadget }
    content     { Faker::JapaneseMedia::Doraemon.gadget }

    association :user
    association :party

    after(:build) do |review|
      review.image.attach(io: File.open('public/images/test_image.jpg'), filename: 'test_image.jpg')
    end
  end
end
spec/factories/parties.rb


FactoryBot.define do

  factory :party do
    name         { Faker::JapaneseMedia::Doraemon.character }
    introduction { Faker::JapaneseMedia::Doraemon.character }
    season_id    { 2 }
    country_id   { 2 }
    genre_id     { 2 }
    official_url { Faker::JapaneseMedia::Doraemon.character }

    association :user


    after(:build) do |party|
      party.image.attach(io: File.open('public/images/test_image.jpg'), filename: 'test_image.jpg')
    end
  end
end

spec/factories/users.rb
FactoryBot.define do

  factory :user do
    nickname              { Faker::JapaneseMedia::Doraemon.character }
    email                 { Faker::Internet.free_email }
    password              { Faker::Internet.password(min_length: 6) }
    password_confirmation { password }
    gender_id             { 2 }
    profile               {Faker::JapaneseMedia::Doraemon.gadget}
    genre_id              { 2 }
    admin                 { false }
  end

  factory :admin_user do
    nickname              { Faker::JapaneseMedia::Doraemon.character }
    email                 { Faker::Internet.free_email }
    password              { Faker::Internet.password(min_length: 6) }
    password_confirmation { password }
    gender_id             { 4 }
    profile               {Faker::JapaneseMedia::Doraemon.gadget}
    genre_id              { 4 }
    admin                 { true }
  end

end

association :reviewをusers.rbのところに書いてみたり色々やってみたけど関係ないエラーになる。

やってみたこと

色々調べてみたところテストのときに使っているletの部分を変えると良さそうだった。

spec/system/reviews_spec.rb
RSpec.describe "Reviews", type: :system do
  let(:admin_user) { FactoryBot.create(:user, admin: true) }
 #let(:party) { FactoryBot.create(:party) }  ⬅️ここを下記コードに変更
  let(:party) { FactoryBot.create(:party, user: user) }  ⬅️追記した
  let(:user) { FactoryBot.create(:user) }

〜以下略〜

これでエラーが消えた。

原因としてはlet(:user)を定義しているのだが、partyインスタンスの作成時に新たにuserを作成してそれを紐付けているため、同じユーザーが既にいることによってエラーになっていたようだ。

引数にuserが必要なケースだったので、テスト内で作成したlet(:party)にそのuserを関連付けてみたところ、これで良かったらしい。

今日も一つ成長。
俺はエラーを越えて強くなる(誰

参考にさせて頂きました

@eitches
Rspecの関連まわりで「バリデーションに失敗しました」が発生するとき

ありがとうござました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0