2010-08-06 69 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章借用的。