【Rails】RSpecの「describe, context, it, example」使い分けまとめ

スポンサーリンク

 

こんにちは、Railsエンジニアにょけんです。

困ったマン
RSpecを書くときの「describe, context, it」とかの使い分けがよくわからない…

というお悩みを持っている方向けに、違いをカンタンにまとめました。

 

スポンサーリンク

describe, context, it, exampleの使い分け

とりあえず概要だけ書きますが、よくわかんないと思うので後続の例を参考にしてください。

  • describe→大枠を記載(クラス名・メソッド名・アクション名など)
  • context→テストの具体例を記載(場合わけのイメージ)
  • it→期待する結果を「英語で」記載
  • example→期待する結果を「日本語で」記載

テストの目的は、クラス・メソッド・アクションなどがちゃんと想定した動作を行うかの確認ですよね?

コレを考えると、自然に使い分けができます。

 

スポンサーリンク


具体例

例えば、Userクラスで、渡された文字列でUserを検索して結果を返す「searchメソッド」があるとします。

[app/models/user.rb]
class User < ApplicationRecord

scope :search, ->(term) 
  { where("LOWER(message) LIKE ?", "%#{term.downcase}%")

コレをテストする場合を考えます。

 

describe

まず、クラス名・メソッド名などの1番大枠を、describeで記述します。

[spec/models/user_spec.rb]
# クラス名「User」をdescribeで記述
describe 'User' do
  # Userクラスのメソッド名「search」を、describeで記述
  describe '#search' do
  end
end

 

context

次に、テストの具体例をcontextで書いていきます。

searchメソッドで確認すべきことは、「検索文字と一致するユーザーがいればそのユーザーを返す」「一致するユーザーがいなければ空を返す」の2点ですね。

「John」「Ken」という2人のユーザーがいる場合に、「John」「Mike」という文字列で検索した場合を想定しましょう。

[spec/models/user_spec.rb]
# クラス名「User」をdescribeで記述
describe 'User' do
  # Userクラスのメソッド名「search」を、describeで記述
  describe '#search' do

    # 各テストの前にUserを作成
    before do 
      @user = User.create(
        name: "John", 
        email: "test@example.com", 
        password: "i-am-john" 
      ) 

      @other_user = User.create(
        name: "Ken", 
        email: "test2@example.com", 
        password: "i-am-ken" 
      ) 
    end   

    # "John"で検索した場合
    context "search by 'John'" do
    end

    # "Mike"で検索した場合
    context "search by 'Mike'" do
    end
  end
end

 

it, example

contextの中に、「期待する結果」をit or exampleで書いていきます。

itは英語で書く場合、exampleは日本語で書く場合に使うことが多いです。

[spec/models/user_spec.rb]
# クラス名「User」をdescribeで記述
describe 'User' do
  # Userクラスのメソッド名「search」を、describeで記述
  describe '#search' do

    # 各テストの前にUserを作成
    before do 
      @user = User.create(
        name: "John", 
        email: "test@example.com", 
        password: "i-am-john" 
      ) 

      @other_user = User.create(
        name: "Ken", 
        email: "test2@example.com", 
        password: "i-am-ken" 
      ) 
    end   

    # "John"で検索した場合
    context "search by 'John'" do
      it "returns @user" do
        expect(User.search("John")).to include(@user)
      end
    
      example "@other_userを返さない" do
        expect(User.search("John")).to_not include(@other_user)
      end
    end

    # "Mike"で検索した場合
    context "search by 'Mike'" do
      # 空を返す
      expect(User.search("Mike")).to be_empty
    end
  end
end

 

スポンサーリンク