2014-05-14 34 views
1

我有一系列的RSpec測試 - 每個都有自己的文件 - 都需要一個特定的對象來運行(shop)。如何將外部對象傳遞給rspec測試?

由於設置shop對象很複雜,我想要一個主文件構建shop對象,然後依次將它傳遞給所有RSpec測試文件。這個想法是編寫測試腳本的人不需要知道關於設置步驟的任何信息。

我無法弄清楚如何將來自外部世界的東西帶入rspec測試用例。我曾嘗試變化周圍的臺詞:

文件master.rb:

describe "Testing tests/some_test.rb" do 
    before :all do 
    @shop = some_complex_operations 
    end 
    load 'tests/some_test.rb' 
end 

文件測試/ some_test.rb:

describe 'Some feature' do 
    it 'should know about @shop' 
    expect(@shop).not_to be nil 
    end 
end 

當我運行rspec master.rb然後some_test.rb失敗。

我知道我所概述的可能是一個非常錯誤的方式去做這件事,但我希望至少你能明白。

我該如何幹淨地實施這樣的事情?

回答

1

你需要的是一個global hook

您可以創建一個spec_helper並在那裏添加全局鉤子。例如:

RSpec.configure do |config| 
    config.before(:each) do 
    @shop = "in case you need a fresh instance of shop each time" 
    end 
    config.before(:all) do 
    @shop = "in case you need a single instance (i.e. you don't modify it)" 
    end 
end 

然後你應該從你的每個規格要求這個幫手。 spec_helper可以存儲任何全局鉤子以及幫助程序或測試的其他依賴項。

0

當你正在寫測試時,應該測試一個的東西。 shop可能是一個非常複雜的對象,許多對象和方法與其交互,但我應該猜想它們都知道shop的複雜性 - 每種方法都對方面shop感興趣。

因此,我建議,而不是建立一個複雜的對象爲每個測試,使得它的double,使其期待什麼是相關的,然後簡單地存根休息:

describe 'Some feature' do 
    let(:shop) { double('shop').as_nil_object } 
    let(:my_object) { MyClass.new(shop: shop) } 


    it 'should do something awesome with shop' do 
    expect(shop).to receive(:awesome_data).and_return(my_data: 'is_this') 

    expect(my_object.do_something_awesome).to eq 'how awesome is_this?' 
    end 
end 
+0

我不確定要明白:這段代碼如何知道商店對象?此外,我的測試只會測試一件事,也許我解釋不正確,商店可以被認爲是上下文的一部分 – djfm

+0

我已經修改了我的答案,使用'let'來創建'shop',並且上下文對象.. –

+0

好吧,明白了。但這並不能真正解決我的問題。更具體地說:我有rspec測試文件,應該在不同版本的應用程序上運行。商店對象封裝了給定版本的應用程序的環境設置。我想避免在測試腳本中提及任何版本,因此我試圖從外部「注入」商店到測試中。在您的提案中,對象仍然沒有「注入」:spec文件構建它。 – djfm