23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RSpec+FactoryBot+Springでエラーが発生したお話

Last updated at Posted at 2019-02-27

#はじめに
Deviseを利用したWebアプリを作成しており、RSpecを用いたテストを実装しています。
FactoryBotを使い早速Userモデルのモデルスペックを作成し始めたのですが、エラーが発生してしまいました。
一応、解決することができたので、事態をメモしたいと思います。

#環境

ruby                  : 2.5.1
rails                 : 5.2.2
device                : 4.6.1
rspec-rails           : 3.8.2
factory_bot_rails     : 5.0.1
capybara              : 3.13.2
spring-commands-rspec : 1.0.4

#事態
###前提
ユーザーに関するファクトリーとモデルスペックは以下の通りです。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "User#{n}" }
    sequence(:email) { |n| "tester#{n}@example.com" }
    password "password"
    password_confirmation "password"
  end
end
spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  it "is valid with a name, email,password and password_confirmation" do
    expect(build(:user)).to be_valid
  end
end

###エラー内容
#####1. NoMethodError
上記の通りファクトリーとモデルスペックを作成してbundle exec rspec spec/models/user_spec.rbを執行したところ以下のエラーが発生しました。

An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error: password "password"


NoMethodError:
  undefined method 'password' in 'user' factory
# ./spec/factories/users.rb:5:in `block (2 levels) in <main>'
# ./spec/factories/users.rb:2:in `block in <main>'
# ./spec/factories/users.rb:1:in `<main>'
# ./config/environment.rb:5:in `<top (required)>'

# ./spec/rails_helper.rb:4:in `require'
# ./spec/rails_helper.rb:4:in `<top (required)>'
# ./spec/models/user_spec.rb:1:in `require'
# ./spec/models/user_spec.rb:1:in `<top (required)>'
No examples found.

Finished in 0.00064 seconds (files took 2.23 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

ファクトリーにパスワード設定しているのになんでpasswordがないと言われるのか全く分からず途方に暮れましたが以下で解決しました。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "User#{n}" }
    sequence(:email) { |n| "tester#{n}@example.com" }
    password  { "password" }
    password_confirmation { "password" }
  end
end

そうです、"password"を{}でくくったことで解決しました。
RSpecを使用するにあたり、Everyday Rails - RSpecによるRailsテスト入門やQiitaで勉強していたのですが、特段{}をつけていなかったので同様に私も外していました。
ただFactoryBot-Getting startedを見ると、すべて{}で囲われていたので試しに囲ってみたら解決した次第です。
今のFactoryBotのバージョンには{}が必要なのでしょうか、、、

#####2.KeyError
そういえばspring-commands-rspecをインストールしていたので、bin/rspec spec/models/user_spec.rbでRSpecを実行してみたところ、今度は違うエラーが発生しました。

$ bin/rspec spec/models/user_spec.rb
Running via Spring preloader in process 99000
Failures:

  1) User is valid with a name, email,password and password_confirmation
     Failure/Error: expect(build(:user)).to be_valid

     KeyError:
       Factory not registered: "user"
     # ./spec/models/user_spec.rb:5:in `block (2 levels) in <main>'
     # -e:1:in `<main>'
     # ------------------
     # --- Caused by: ---
     # KeyError:
     #   key not found: "user"
     #   ./spec/models/user_spec.rb:5:in `block (2 levels) in <main>'

ユーザーが見つからないってどういうこと、、、とこれまた途方に暮れたのですが、spec/factories以下に正しいfactoryの定義が存在するのにFactory not registeredArgumentError: Factory not registeredを参考にして、spec_helper.rbに以下追加したところ解決しました。

spec/sepc_helper.rb
RSpec.configure do |config|
  config.before(:all) do
    FactoryBot.reload
  end
end

#参考記事
Railsの開発効率をあげる - Springを使ってRailsのコンソールコマンドの実行を早くする

23
22
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
23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?