2012-05-11 34 views
3

下面的代碼無法正常工作,但它最好的證明就是我想要達到是否可以在Rspec中訪問周圍環境的主題?

context "this context describes the class" do 

    subject do 
    # described class is actually a module here 
    c = Class.new.extend(described_class) 
    c.some_method_that_has_been_added_through_extension 
    c 
    end 

    # ... testing the class itself here ... 

    context "instances of this class" do 

    subject do 
     # this doesn't work because it introduces a endless recursion bug 
     # which makes perfectly sense 
     subject.new 
    end 

    end 

end 

我也試過在我與對象初始化 內上下文中使用一個局部變量,但沒有運氣。有沒有什麼方法可以在內部範圍內的主題定義中訪問外部範圍的主題?

回答

0

東西明顯作品在內上下文是使用實例變量並與subjectsubject.call,而不是初始化它不是。主題是Procs。因此,我的第一種方法沒有奏效。

context "instances of this class" do 

    klass = subject.call 
    subject { klass.new } 

end 
3

使用#subject有時會導致麻煩。它是「主要用於」像#its這樣的簡短檢查。

它也可以讓示例更難閱讀,因爲它可以用來掩蓋您測試的名稱/意圖。這裏有一個博客帖子,大衛赫利姆斯基上#subject和#let的主題,其揭示的意圖作用寫道:http://blog.davidchelimsky.net/blog/2012/05/13/spec-smell-explicit-use-of-subject/

嘗試使用讓利,而不是 https://www.relishapp.com/rspec/rspec-core/v/2-10/docs/helper-methods/let-and-let

這裏是我很可能會寫。

context "this context describes the class" do 
    let(:name_of_the_module) { Class.new.extend(described_class) } 
    before do 
    c.some_method_that_has_been_added_through_extension 
    end 

    # ... testing the class itself here ... 

    context "instances of this class" do 

    let(:better_name_that_describes_the_instance) { klass.new } 

    # ... test the instance 
    end 

end 

阿里納斯 您可能要重新考慮是否要使用主題在所有。我更喜歡在幾乎所有情況下使用#let。 YMMV

0

我一直在尋找解決方案,但出於不同的原因。當我測試可能返回值或引發錯誤的方法時,我經常需要在兩個上下文中重複該主題,一次是作爲raise_error的處理程序,並且一次是正常的。

我發現的是,您可以給subjects名稱,如lets。這讓我們從一個新的subject內的外部示波器引用一個名爲subject。下面是一個例子:

describe 'do_some_math' do 
    let!(:calculator) { create(:calculator) } 

    # proc to be used with raise_error 
    subject(:do_some_math) { 
    -> { calculator.do_some_math(with, complicated, args) } 
    } 

    context 'when something breaks' do 
    it { is_expected.to raise_error } # ok 
    end 

    context 'when everything works' do 

    # here we call the named subject from the outer scope: 
    subject { do_some_math.call } # nice and DRY 

    it { is_expected.to be_a(Numeric) } # also ok! 
    end 
end 
相關問題