干涸 - RSpec和Mocking问题

时间:2010-08-06 05:42:53

标签: ruby mocking rspec bdd

在.net世界中,我的规格将遵循Arrange,Act,Assert模式。我在rspec中复制它时遇到了麻烦,因为在SUT采取行动后,似乎没有能力选择性地验证你的模拟。再加上每个'It'块结束时评估每个期望的事实,都会让我在很多规范中重复自己。

这是我正在谈论的一个例子:

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个断言块)。我还需要复制模拟设置,以便它在前一个块中存根,但在it / assertion块中单独预期。我在这里重复或几乎复制了大量的代码。我认为它甚至比突出显示更糟糕,因为很多这些全局变量只是单独定义,以便以后可以通过'期望'测试来消耗它们。有没有更好的方式我还没看到呢?

(SUT =正在测试的系统。不确定这是不是每个人都称之为,或者只是alt.net人员)

2 个答案:

答案 0 :(得分: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章。

答案 1 :(得分:0)

如果有帮助,你可以使用“上下文”将它们分开......

http://wiki.github.com/dchelimsky/rspec/faq