前提
context "ユーザを生成" do
subject { User.create(name: "John") }
it "ユーザが1つ生成される" do
is_expected.to change(User.count).by(1)
end
end
subjectとして、ユーザ生成のためのメソッドを定義しました。
この状態で、生成されたユーザ名が"John"であることを、同じsubjectでテストしたいことがありました。
うまくいかない場合
it "ユーザ名がJohnである" do
subject
expect(User.last.name).to eq("John")
end
こうしてもUser.lastがnilですよ、というエラーが出て、どうやらsubjectの中身が実行されていない様子。
原因究明
puts subject.class
としてクラスを調べると、
Proc
と返ってくる。
rubyではProcクラスという、実行コード自体を変数に格納するクラスが存在しています。
したがって
subject
として書いても
"文字列"
とか書いているのと同じようなもので、何も起こりません。
したがってProcクラスのオブジェクトとして実行してやる必要があります。
解決方法
実行の方法は様々ですが、一例でいうと
subject.call
があります
したがって
it "ユーザ名がJohnである" do
subject.call
expect(User.last.name).to eq("John")
end
これでパスしました。
別のコンテキストにしろよ、とか、subjectの設定がいまいち、とかもあるかもしれませんが、同じ状況に直面したらぜひご一考をば。
全体のコード
context "ユーザを生成" do
subject { User.create(name: "John") }
it "ユーザが1つ生成される" do
is_expected.to change(User.count).by(1)
end
it "ユーザ名がJohnである" do
subject.call
expect(User.last.name).to eq("John")
end
end
以上です。