2
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 1 year has passed since last update.

【Rspec】letとlet!、beforeの違い

Posted at

##letlet!の違い
letは遅延評価と呼ばれ、テスト内でメソッドを使用した時に初めて評価(定義)され、

let!はテストが実行される前(it内のテストが実行される前)に評価(定義)される。

■let

 describe 'letの挙動を確認' do
    let(:user) { build(:user) }

    it 'userインスタンスが有効であること' do
      expect(user).to be_valid 
             ※↑ここではじめて読み込まれる
    end
  end

上記のようにletは呼び出された時に、はじめてデータを読み込むので無駄にデータベースに問い合わせてしまってテストが遅くなるといったことを予防してくれる。

■let!

describe 'let!の挙動を確認' do
    let(:user) { create(:user) }
    let!(:user_task) { create(:task, user_id: user.id, title: 'test_title') } 

    it 'userがtaskを持っていること' do
      expect(user.tasks.first.title).to eq 'test_title' 
    end
  end

taskインスタンスの入った変数「user_task」が作成されたのち、expect内のテストが実行される。

##beforeとの違い
letlet! 以外によく聞くのはbeforeだが、beforelet!と挙動がさほど変わらないと言っていい。

let!と主な違う点は、インスタンス変数の定義以外にも使用できることである。

describe 'beforeの挙動を確認' do
    let(:user) { create(:user) }
    before { login(user) } #loginメソッドを定義している前提

    it 'is success to edit user' do
      visit edit_user_path(user)
      fill_in "Email", with: "edit_user@example.com"
      click_button "Update"
      expect(page).to have_content 'User was successfully updated.'
      expect(current_path).to eq user_path(user)
    end
  end

例えば、ログイン後の動作をテストしたい場合、このテストコードの内容を見ると、既にログインをすましていて、ユーザープロフィールなどを更新できるかのテストを行っている。

この**「既にログインを済ます」**箇所がbeforeにあたる。

またlet!beforeの実行順序は定義した順番で実行される。

##let /let!/ beforeの使い分け

let:テストで何回か使うインスタンス変数がある時
let!:テストのブロック内で毎回使うインスタンス変数がある時
before:テストのブロック内で毎回適用させたいメソッドなど(インスタンス変数以外)がある時

##参考記事
【RSpec】"let"と"let!"とbeforeの違いと実行順序

2
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
2
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?