katou02
@katou02 (Meitoku)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Rspec 条件つきバリデーションでエラー

現在createアクションの時だけ実行するバリデーションを用意しています
この影響で、Rspeのテストの時にエラーが発生します

validates :nickname,:email,:password,presence: true, on: :create

Rspec

uspec/factories/user.rb
FactoryBot.define do
  factory :user do
    nickname { "test" }
    email { "test@gmail.com" }
    password { "test2020" }
    password_confirmation { "test2020" }
  end
end
spec/models/user_spec.rb
  require 'rails_helper'

  RSpec.describe Tweet, type: :model do

    before do
      @user = create(:user)
    end

    context 'nicknameカラム' do
      it '未入力でないこと' do
        @user.nickname = ''
        is_expected.to eq false
      end
    end
  end

エラー

  1) User バリデーションテスト nicknameカラム 未入力でないこと
     Failure/Error: is_expected.to eq false

       expected: false
            got: true

       (compared using ==)

       Diff:
       @@ -1 +1 @@
       -false
       +true

     # ./spec/models/user_spec.rb:19:in `block (4 levels) in <top (required)>'

createアクションのみではなく、常にバリデーションを実行するとエラーは発生しません
こちらがヒントになるのかと読んでみましたが、エラーは変わりません
よろしくお願いします

0

1Answer

サンプルコードにsubject{}がないので、is_expected.to eq falseがどういう値を確認しているのか分かりませんが、多分こういうことじゃないかと

require 'rails_helper'

RSpec.describe Tweet, type: :model do

  subject{ build(:user) }

  it "factory初期値でエラーはない" do
    # expect(subject).to be_valid
    is_expected.to be_valid
  end

  context 'nicknameカラム' do
    it '未入力でないこと' do
      subject.nickname = ''
      # expect(subject).not_to be_valid
      is_expected.not_to be_valid
    end
  end
end

rspecでインスタンス変数を使うのは余りいい傾向じゃなかったような ... 通常こういう場合はletを使うと思います。

あと、on: :createのバリデーションだとcreate(...)した時点で、それ以降はエラーがあるかないかのチェックが出来なくなるので、build(...)の方がやりたいことなんじゃないかと。

1Like

Comments

  1. @katou02

    Questioner

    ありがとうございます!

Your answer might help someone💌