2013-10-27 83 views
1

是我工作中的編碼標準規定了一組規格測試的功能應該有一個主題就是被調用的函數。它看起來像這樣:rspec記憶「主題」塊嗎?

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,我們將受益於內置記憶化或其他的加速僅具有每級一個主題塊?

Asside:

我遇到了一種情況,我們的風格不起作用。使用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 

有沒有其他的問題,我應該留意這種風格?

+0

我可能會錯過一些東西,爲什麼你的Bar存根會導致問題?該主題尚未被調用,所以斷言仍應在該方法運行之前設置。 – Shepmaster

+0

在'之前'區塊中,我不會扼殺'Bar'。我在'Bar'的任何實例上對方法'baz()'進行了存根。我的第一個傳球是:'Bar.stub(:baz)}'之前也有效。但是,這並沒有通過代碼審查,所以我需要修改'before'塊。 – user2574255

+0

對不起,我並不清楚 - 我確實意味着磕碰'上的所有'Bar's baz'。但是,我仍然不明白你的測試失敗的原因。你能否將你的例子更新爲可運行的? 'define'在這裏不是一個有效的關鍵字,我想你可以刪除對ActiveModel和FactoryGirl的引用。也許這也會使問題更具責任感。 – Shepmaster

回答

2

subject是懶惰地創建,每個測試和範圍爲context/describe,就像let一樣。不應該有任何額外的開銷給他們。

我不親自喜歡你展現的風格,但我做的時候我已經很複雜(或只是大)的數據對象相似,以至於從一個方法返回的東西。

describe "A thing" do 
    subject(:foo) { FactoryGirl.create(:foo) } 

    # A very complicated object from this method 
    describe "the result of calling frob" do 
    subject(:result) { foo.frob } 

    it { should be_active } 
    it { should be_alive } 
    end 
end 
+0

對不起,如果我的問題不清楚。我沒有問是否有額外的開銷來使用'subject'。我在問,是否有額外的開銷讓你不能在任何地方使用相同的主題。基本上,有沒有我們沒有利用的主題所做的一些備忘錄。我將編輯這個問題來澄清。感謝你的回答。 – user2574255

+0

嗯,我無意中回答了這個問題太 - '一個測試期間subject'是memoized,但它是*每個測試中*,因此它的每一次復位。你可能有成千上萬個「主題」塊(這將是一個壞主意^ _ ^),唯一的額外時間將用於解析文件。 – Shepmaster

+0

謝謝。這很好。我們確實有數千個「主題」塊。沒有人問我是否是一個壞主意,但事情是如何完成的。只要團隊在同一頁面上,我不會太在意與其他人做的事情不同。至少這就是我試圖告訴自己:) – user2574255