Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
45
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@kuboon

describe の次行に subject を、 context の次行に let を書く

というオレオレルールなんですが、わりといい気がするのでご紹介します。

よくわからないと思うので実例で。

実例

狼が村人を噛むと村人は死ぬ。狼がハムスターを噛んでもハムスターは死なない という条件の rspec を、以下のように書きます。

wolf_spec.rb
require 'rails_helper'

RSpec.describe Wolf do
  subject(:wolf){ FactoryGirl.build(:wolf) }
  it { is_expected.to be_valid }
  describe 'bite' do
    subject { wolf.bite(creature) }
    context 'bite villager' do
      let(:creature){ FactoryGirl.build(:villager) }
      it { expect{subject}.to change{creature.reload.living?}.to(false) }
    end
    context 'bite hamster' do
      let(:creature){ FactoryGirl.build(:hamster) }
      it { expect{subject}.not_to change{creature.reload.living?} }
    end
  end  
end

順に上から見て行きましょう。

describe Wolf do
  subject(:wolf){ FactoryGirl.build(:wolf) }

まず、この2行がペアです。 Wolf モデルに関するテストであるという宣言と、実際に wolf のインスタンスを用意する ruby 文とのペアです。 subject に引数を渡しているので、 wolf でも subject でも同じものを参照できます。

次の行。

it { is_expected.to be_valid }

is_expectedexpect(subject) と等価です。実行文そのものがテスト内容を完全に表現しているので、 it にコメントは不要でしょう。

その次の2行を見てみましょう。

  describe 'bite' do
    subject { wolf.bite(creature) }

biteメソッドをテストするよ!という宣言と、実際に wolf の bite メソッドを呼び出す ruby 文とのペアです。
先の subject で引数を渡しているので、 wolf で参照できます。 creature はこの時点では未定義です。

次の2行を御覧ください。

    context 'bite villager' do
      let(:creature){ FactoryGirl.build(:villager) }

villager を bite した時のテストだよ!という宣言と、biteに引数として渡してある creature に villager のインスタンスを実際に渡す ruby 文とのペアです。

次の行はテストの本体になります。

it { expect{subject}.to change{creature.reload.living?}.to(false) }

今回は change マッチャの都合で is_expected が使えませんが、英文として読んだ通りのテストなので、やはり it にコメントは不要でしょう。

まとめ

describe と context の実装は alias なのでどっちを使っても実質同じなのですが、英単語の意味で使い分け、「何をテストするか」を describe, 「どんな状況のテストをするか」を context でまとめると分かりやすい、と言われています。
一方、subject と let も (ほぼ) alias でして、英単語の意味的に使い分けているだけなのですが、 subject は「何をテストするか」の宣言なので、これを describe と対応させ、 context は let で書くようにすると書き方に統一感が生まれ、読みやすい spec になるんでは、という提案でした。

完全にこのルールで全てを書けるわけではなく、describe と let がペアになるケースも実際に私の手元で発生はしていますが、 describeとかcontextのコメントを書いたら、次の行にそのコメントに対応するruby文を書く というルールは確実に可読性を上げるのでオススメです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
45
Help us understand the problem. What are the problem?