LoginSignup
0
0

More than 1 year has passed since last update.

【Rspec】build/createの違いと新規登録テストのエラー:expected `User.count` to have changed by 1, but was changed by 0について

Last updated at Posted at 2021-10-27

はじめに

buildとcreateの違いすらよく理解せずに新規登録テストをRspecで書いて実行したところ、タイトルのようなエラーが発生しました。解決までに2時間ほどかかったので記念としてまとめておきます。なお、Railsのバージョンは5.2.6で、FactoryBotとFakerを導入しています。

背景

Rspecによくある新規登録のテストをしたかったので、まず、以下のように書きました。

spec/test_spec.rb
describe 'テスト①:ユーザー新規登録のテスト' do
  let!(:user) { create(:user) }

  before do
    visit new_user_registration_path
    fill_in 'user[name]', with: user.name
    fill_in 'user[email]', with: user.email
    fill_in 'user[password]', with: user.password
    fill_in 'user[password_confirmation]', with: user.password_confirmation
  end

  context '新規登録成功のテスト' do
    it '正しく新規登録される' do
      expect { click_button "新規登録" }.to change { User.count }.by(1)
    end
  end
end

これを実行すると、以下のようなエラーが、、

Failures:

  1) テスト①:ユーザー新規登録のテスト 新規登録成功のテスト 正しく新規登録される
     Failure/Error: expect { click_button "新規登録" }.to change { User.count }.by(1)
       expected `User.count` to have changed by 1, but was changed by 0

とりあえず、pry-byebugでデバッグすることに。テストファイルの問題の行の前にbinding.pryを入れて実行してみました。

spec/test_spec.rb
it '正しく新規登録される' do
  binding.pry
  expect { click_button "新規登録" }.to change { User.count }.by(1)
end
    16:   context '新規登録成功のテスト' do
    17:     it '外部キー入力を求められることなく正しく新規登録される' do
    18:       binding.pry
 => 19:       expect { click_button "新規登録" }.to change { User.count }.by(1)
    20:     end
    21:   end
    22: end
    23: 
    24: describe 'エラー②:フレンドリーフォワーディングの確認(新規登録・ログイン後の画面遷移先のテスト)' do

[1] pry(#<RSpec::ExampleGroups::Nested::Nested>)> User.count
=> 1
[2] pry(#<RSpec::ExampleGroups::Nested::Nested>)> User.first
=> #<User id: 1, email: "stephen@skiles-dooley.name", name: "k7hpuyja56", created_at: "2021-10-27 08:56:10", updated_at: "2021-10-27 08:56:10">

新規登録ボタンを押してないのにもうユーザーが登録されてる?なんで??賢明な諸君はもうお気づきでしょうが、結構悩みました。

解決方法

 単純に、let!(:user) { create(:user) }としていることが原因でした。create時にDBに一人のユーザーが保存されてしまい、新規登録ボタンを押す前に既にUser.count = 1となってしまっているんですね。
 正しくは、以下のようにbuildを使う必要があります。

spec/test_spec.rb
describe 'テスト①:ユーザー新規登録のテスト' do
  let!(:user) { build(:user) }

  before do

  (以下略)

これで無事テストが通るようになりました。めでたしめでたし

最後に

 初歩的なミスでしたが、buildとcreateの違いを理解する良いきっかけとなりました。基本的にcreateを使って書けば良いと思うのですが、DBに保存するような類のテストでは注意が必要だと思いました。

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