2010-08-06 2 views
1

В мире .net мои спецификации будут следовать шаблону Arrange, Act, Assert. У меня возникли проблемы с репликацией в rspec, потому что, как представляется, нет возможности выборочно проверять ваши макеты после того, как SUT принял это действие. Это в сочетании с тем фактом, что каждое ожидание оценивается в конце каждого блока «Это», заставляет меня повторять себя во многих моих спецификациях.DRY the 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 блоков утверждения). Я также должен дублировать установку mock так, чтобы она была заштрихована в предыдущем блоке, но индивидуально ожидалась в блоке it/assertion. Я дублирую или почти дублирую тонну кода здесь. Я думаю, что это еще хуже, чем указывает подсветка, потому что многие из этих глобалов определяются только по отдельности, чтобы потом их можно было использовать при тестировании «ожиданий». Есть ли лучший способ, который я пока не вижу?

(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 

Другой метод заключается в использовании макросов, что очень удобно, если вам нужно аналогичный спецификации в разных классах.

Примечание: приведенный выше пример заимствован из The RSpec Book, глава 12.

Смежные вопросы