RSpecの難しさ
RSpecの文法に触れる機会が多いのであれこれこねくり回している。
def hoge(key) {a: "AAA", b: "BBB", c: "CCC"}[key] end
のテストをどう書く?
一つのit にまとめて should
describe "#hoge" do it "hoge がなんか返す" do hoge(:a).should == "AAA" hoge(:b).should == "BBB" hoge(:c).should == "CCC" hoge(:d).should be_nil end end
it を分割
describe "#hoge" do it "keyが :aの場合は AAAを返す" do hoge(:a).should == "AAA" end it "keyが :bの場合は BBBを返す" do hoge(:b).should == "BBB" end it "keyが :cの場合は CCCを返す" do hoge(:c).should == "CCC" end it "keyが :dの場合は nilを返す" do hoge(:d).should be_nil end end
配列で データドリブンテスト
describe "#hoge" do [["keyが :aの場合は AAAを返す", :a, "AAA"], ["keyが :bの場合は BBBを返す", :b, "BBB"], ["keyが :cの場合は CCCを返す", :c, "CCC"], ["keyが :dの場合は nilを返す", :d, nil], ].each do |desc, input, expected| it desc do hoge(input).should == expected end end end
subject & context
describe "#hoge" do subject { hoge(fuga_key) } context "keyが :aの場合は AAAを返す" do let(:fuga_key) { :a } it { should == "AAA" } end context "keyが :bの場合は BBBを返す" do let(:fuga_key) { :b } it { should == "BBB" } end context "keyが :cの場合は CCCを返す" do let(:fuga_key) { :c } it { should == "CCC" } end context "keyが :dの場合は nilを返す" do let(:fuga_key) { :d } it { should be_nil } end end
shared_context
shared_context "subject" do subject{hoge(key)} end describe "#hoge" do include_context "subject" context ":a なら AAA" do let(:key){:a} it{ should == "AAA"} end context ":b なら BBB" do let(:key){:b} it{ should == "BBB"} end context ":c なら CCC" do let(:key){:c} it{ should == "CCC"} end context ":d なら nil" do let(:key){:d} it{ should be_nil } end end
shared_examples
shared_examples "#hoge はなんか返す" do subject{hoge(key)} it{ should == expected } end describe "#hoge" do context ":a なら AAA" do let(:key){:a} let(:expected){"AAA"} it_behaves_like "#hoge はなんか返す" end context ":b なら BBB" do let(:key){:b} let(:expected){"BBB"} it_behaves_like "#hoge はなんか返す" end context ":c なら CCC" do let(:key){:c} let(:expected){"CCC"} it_behaves_like "#hoge はなんか返す" end context ":d なら nil" do let(:key){:d} let(:expected){nil} it_behaves_like "#hoge はなんか返す" end end
今回のケースだとshared_context、shared_examplesはやらないだろうが、
たった3行メソッドでも書き方がいろいろ考えられる。
RSpecの欠点は、選択肢の多さだろう。学習コストは高い。
追記
後輩から突っ込みが。
def hoge(key) {a: "AAA", b: "BBB", c: "CCC"}[key] end
このメソッドに意図が不明確で解りにくいから、迷うのでは? メソッドを書き換えて、その意図が伝わるように、 describe context subject等をうまく使ってメソッドの意図を捕捉するのでは?
(あるいは順序は逆転して、RSpecの記述で describe context subject等を駆使して考えながら記述することで、
メソッドの意図を明確になるように書き換えるのでは?)、とのフィードバック。
それは確かに一理ある。8割5分同意。1割5分 同意せずかな。
後で書く。