テストの書き方とアプリとしてどうあるべきか
require 'spec_helper' describe Group do describe '#add_member' do subject { group.add_member member } context 'ユーザーを追加した場合' do let(:group) { FactoryGirl.build(:group) } let(:member) { FactoryGirl.build(:member) } it 'グループのメンバーの数が1になること' do expect(subject.members.length).to eq 1 end end end end
最近、こういうテストの書き方している。けど、これあんまりよくない。良くないというか絶対ダメだと思う。
何がダメだと思うか。expectがイケてない気がする。というのもsubjectの結果としてGroupのインスタンスが返ってくるのをまず期待しているというのがイケてない。で、先にテストをこう書いてしまうと実装はこれにインターフェイスをあわせる必要が出てくる。良くない。
けど、この場合どうしたらいいんだろう。メンバーを追加することによって、グループに紐づくメンバーが増えているかを確認したいというのがこのテストの目的。
require 'spec_helper' describe Group do describe '#add_member' do subject { group.add_member member } context 'ユーザーを追加した場合' do let(:group) { FactoryGirl.build(:group) } let(:member) { FactoryGirl.build(:member) } before { subject } it 'グループのメンバーの数が1になること' do expect(group.members.length).to eq 1 end end end end
と書き換えるのもいいかもしれない。けど、subjectがbeforeにきてしまうのちょっと違和感があるのと、これだとgroup.membersが更新前の状態で紐付いているやつがとれてくる可能性があり、あまり良くない。良くないというか、場合によってはコケると思う。テスト。
どうしよう。これはどうだろう?
require 'spec_helper' describe Group do describe '#add_member' do subject { group.add_member member } context 'ユーザーを追加した場合' do let(:group) { FactoryGirl.build(:group) } let(:member) { FactoryGirl.build(:member) } before do subject group.reload end it 'グループのメンバーの数が1になること' do expect(group.members.length).to eq 1 end end end end
むー。良さそうが気がする。結局beforeにsubjectがあるという状態は変わらないので、ちょっとあれなんだけど、そんなにイケてないってほどじゃない気はしている。ふむ…。
実際どうなんだろうなー。こういうの。もっとこういう書き方あるで!ってあったら教えて欲しい感じある。