私が取り組んでいるコーディング標準では、関数をテストする仕様のグループには、呼び出される関数であるサブジェクトが必要であると指定されています。次のようになります。
define User do
context :foo do
let(:user) { FactoryGirl.create(:user) }
subject { user.foo }
it { ... }
end
end
ブロックの典型的な用途は、subject
テストしているクラスをインスタンス化することです:
define User do
subject { FactoryGirl.create(:user) }
it { ... }
end
スタイル ガイドの意図した効果は、テスト対象のメソッドごとに異なるサブジェクト ブロックを用意することです。これは私たちのテストを遅くしていますか? 通常の方法で使用subject
した場合、クラスごとに 1 つのサブジェクト ブロックのみを使用することで、組み込みのメモ化やその他の高速化の恩恵を受けるでしょうか?
余談:
私たちのスタイルがうまくいかないケースに遭遇しました。使用any_instance.should_receive
する場合、スタイル ガイドに従わないと、仕様が常に失敗します。代わりに、より伝統的なアプローチを使用する必要があります。ここでsubject
は、テストしているオブジェクトであり、仕様でそのオブジェクトに対してメソッドを呼び出します。
# passing spec
define Foo do
before { Bar.any_instance.stub(:baz) }
subject { FactoryGirl.create(:foo) }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject.baz_the_bars
end
end
# spec follows style guide but fails
define Foo do
before { Bar.any_instance.stub(:baz) }
let(:foo) { FactoryGirl.create(:foo) }
subject { foo.baz_the_bars }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject
end
end
class Foo
has_many :bars
def baz_the_bars
bars.collect do |bar|
bar.baz
end.count(true)
end
end
このスタイルで他に注意すべき点はありますか?