質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Q&A

解決済

1回答

4101閲覧

factorybot、Rspec 同じモデルの異なる複数のデータを使用する

takeke

総合スコア60

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

0グッド

0クリップ

投稿2018/12/03 01:26

編集2018/12/05 07:44

factorybot とRspecつかってテストしています。テストの際に1つのモデルで中身のデータが異なるものを複数生成してそのJsonの出力を確認したいのですが。やり方がわからず困っています。

同一データを複数生成する方法はわかったのですが、できれば、factories/モデル名s.rbに仮のデータを複数作成して、そちらを適用したいなと考えているのですが、そのようなことはできるでしょうか?

例えばですが、今のfactories/recruits.rb

rails

1FactoryBot.define do 2 factory :recruit_a, class: Recruit do 3 title "title1" 4 status "default" 5 end 6 factory :recruit_b, class: Recruit do 7 title "title2" 8 status "test" 9 end 10 factory :recruit_c, class: Recruit do 11 title "title3" 12 status "end" 13 end 14end

上記の3つのデータをspecで使うようなことです。
let!(:recruit) { create(:recruit_a) }
let!(:recruit) { create(:recruit_b) }
let!(:recruit) { create(:recruit_c) }
などやってみたものの1つしか適用されませんでした。

以上です。何かアドバイスなどいただけると助かりますよろしくお願いいたしますm(__)m

補足

rails

1require 'rails_helper' 2 3RSpec.describe "User::Offer", type: :request do 4 describe "GET /user_offer" do 5 let!(:user_token) { create(:user_token) } 6 let!(:offer) { create(:offer_b) } 7 let!(:user) {create(:user)} 8 create(:recruit, :a)} 9 let(:res) { JSON.parse(response.body).deep_symbolize_keys } 10 context "正常系" do 11 it "詳細が有効" do 12 get '/api/user/offers/2', params: { 13 token: "user_token" 14 } 15 expect~~省略

rails

1Failure/Error: create(:recruit, :a) 2 `create` is not available on an example group (e.g. a `describe` or `context` block). It is only available from within individual examples (e.g. `it` blocks) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc).

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

対策

let は定義なので同じ名前があると上書きされて最後しか実行されません
別名を付けるべきでしょう

ruby

1let!(:recruit_a) { create(:recruit_a) } 2let!(:recruit_b) { create(:recruit_b) } 3let!(:recruit_c) { create(:recruit_c) }

または、定義する必要がない(データだけあれば良い)なら、 let を使わず before で登録しましょう

ruby

1before do 2 create(:recruit_a) 3 create(:recruit_b) 4 create(:recruit_c) 5end

補足

factory自体を分割すると共通設定や共通連番などで困るため trait をお勧めします

ruby

1FactoryBot.define do 2 factory :recruit do 3 sequence(:no) { |n| n } 4 5 trait :a do 6 title "title1" 7 status "default" 8 end 9 10 trait :b do 11 title "title2" 12 status "test" 13 end 14 15 trait :c do 16 title "title3" 17 status "end" 18 end 19 end 20end 21 22create(:recruit, :a) # no=1 23create(:recruit, :b) # no=2 24create(:recruit, :c) # no=3

投稿2018/12/03 03:33

Ighrs

総合スコア656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takeke

2018/12/05 07:01

遅くなりましたが回答ありがとうございます! こちら推奨していただけたtrait使用時、更に関連データ生成するさいには、 trait :a do title "title1" status "default"      after(:create) do |recruit| create(:entry_a, recruit: a) end end のような形で作れますでしょうか? 上記after~はイメージですので通りませんでした
Ighrs

2018/12/05 07:12

trait の指定は指定対象の作成時に使うものです Entry 作成時に Recruit の trait は指定できません after create ならば引数で、指定 trait で作られた recruit があるのでそれを使いましょう after(:create) do |recruit| create(:entry_a, recruit: recruit) end または、Entity側も trait を使うなら以下でしょう after(:create) do |recruit| create(:entry, :a, recruit: recruit) end
takeke

2018/12/05 07:26

度々すみません。そもそも最初のtraitがまだ使えてませんでした。 FactoryBot.define do factory :recruit do sequence(:no) { |n| n } trait :a do title "title1" status "default" end trait :b do title "title2" status "test" end trait :c do title "title3" status "end" end end end がfactories/recruits.rbで create(:recruit, :a) create(:recruit, :b) create(:recruit, :c) は使う画面のspecに記述ですよね?
takeke

2018/12/05 07:32

使っている画面の補足を質問本文に記載しました。
Ighrs

2018/12/05 07:37 編集

あーすみません sequence(:no) は、もし共通定義があったらという説明のために追加しただけで、実際に no カラムがなければ不要です
takeke

2018/12/05 07:47

了解です!あと今追記しましたがエラーがでてしまうのですが、何が問題かお分かりになりそうですか??
takeke

2018/12/05 07:57

before do create(:recruit, :a) create(:recruit, :b) create(:recruit, :c) end beforeしてませんでした。すみません
takeke

2018/12/05 11:24

お騒がせしました。無事実装できました!traitとてもいいですね!今回はrecruitとentryの両方で使わせていただきました。 またご縁がありました際にはよろしくお願いいたします!ありがとうございましたm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問