1
0

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 3 years have passed since last update.

Rspec: subjectにメソッドを設定した場合に、実行後の状態をテストしたい

Posted at

前提

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

以上です。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?