2010-08-06 73 views
1

在.net世界中,我的規格將遵循Arrange,Act,Assert模式。我在rspec中複製它時遇到了問題,因爲在SUT採取行動後,似乎沒有選擇性驗證你的模擬的能力。再加上每個'It'塊的末尾都會評估每個期望,這讓我在很多規範中都重複了自己。DRY SUT up - RSpec和嘲諷問題

這裏就是我談論的例子:

describe 'AmazonImporter' do 
    before(:each) do 
     Kernel.**stubs**(:sleep).with(1) 
    end 
    # iterates through the amazon categories, and for each one, loads ideas with 
    # the right response group, upserting ideas as it goes 
    # then goes through, and fleshes out all of the ideas that only have asins. 
    describe "find_new_ideas" do 
     before(:all) do 
      @xml = File.open(File.expand_path('../amazon_ideas_in_category.xml', __FILE__), 'r') {|f| f.read } 
     end 

     before(:each) do 
      @category = AmazonCategory.new(:name => "name", :amazon_id => 1036682) 
      @response = Amazon::Ecs::Response.new(@xml) 
      @response_group = "MostGifted" 
      @asin = 'B002EL2WQI' 
      @request_hash = {:operation => "BrowseNodeLookup", :browse_node_id => @category.amazon_id, 
                :response_group => @response_group} 
      Amazon::Ecs.**expects**(:send_request).with(has_entries(@request_hash)).returns(@response) 
      GiftIdea.expects(:first).with(has_entries({:site_key => @asin})).returns(nil) 
      GiftIdea.any_instance.expects(:save)    
     end 

     it "sleeps for 1 second after each amazon request" do 
      Kernel.**expects**(:sleep).with(1) 
      AmazonImporter.new.find_new_ideas(@category, @response_group) 
     end 

     it "loads the ideas for the given response group from amazon" do 
      Amazon::Ecs.**expects**(:send_request). 
       with(has_entries(@request_hash)). 
       returns(@response) 

      **AmazonImporter.new.find_new_ideas(@category, @response_group)** 
     end 

     it "tries to load those ideas from repository" do 
      GiftIdea.expects(:first).with(has_entries({:site_key => @asin})) 
      **AmazonImporter.new.find_new_ideas(@category, @response_group)** 
     end 

在這個部分例子,我測試的find_new_ideas方法。但我必須爲每個規格調用它(全規範有9個斷言塊)。我進一步必須複製模擬設置,以便它在前面的塊中被樁住,但是在它/斷言塊中單獨地被期望。我在這裏重複或幾乎複製了大量的代碼。我認爲這比突出顯示更糟糕,因爲很多這些全局變量只是單獨定義的,以便以後可以通過「預期」測試來使用它們。有沒有更好的方式我還沒有看到?

(SUT =被測系統。不知道是否這就是大家都叫它,或者只是alt.net人)

回答

1

您可以使用共享的例子組以減少重複:

shared_examples_for "any pizza" do 
    it "tastes really good" do 
    @pizza.should taste_really_good 
    end 
    it "is available by the slice" do 
    @pizza.should be_available_by_the_slice 
    end 
end 

describe "New York style thin crust pizza" do 
    before(:each) do 
    @pizza = Pizza.new(:region => 'New York' , :style => 'thin crust') 
    end 

    it_behaves_like "any pizza" 

    it "has a really great sauce" do 
    @pizza.should have_a_really_great_sauce 
    end 
end 

另一種方法是使用宏,這是方便,如果你需要類似的SP在不同的課程中。

注意:上面的例子是從The RSpec Book,第12章借用的。