zoukankan      html  css  js  c++  java
  • RSpec shared examples with template methods

    It’s pretty common to have multiple tests that are nearly the same.

    In one app, we support bidding on both online and hammer auctions (auctions with people physically present). They’re separate controllers but with a lot of shared code and behavior.

    We want to test both, but we’d rather not write two almost identical tests if we can help it.

    So we’ve been using RSpec shared examples, with the template method patternto account for the differences, and we like it.

    Here’s a simplified example:

    spec/request/online_bidding_spec.rb

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    require "spec_helper"
    require "support/shared_examples/bidding"
    
    describe "Bidding online" do
      include_examples :bidding
    
      let(:auction) { FactoryGirl.create(:online_auction) }
    
      def auction_path
        online_auction_path(auction)
      end
    end
    

    spec/request/hammer_bidding_spec.rb

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    require "spec_helper"
    require "support/shared_examples/bidding"
    
    describe "Bidding at hammer auction" do
      include_examples :bidding
    
      let(:auction) { FactoryGirl.create(:hammer_auction) }
    
      def auction_path
        hammer_auction_path(auction)
      end
    end
    

    spec/support/shared_examples/bidding.rb

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    shared_examples :bidding do
      it "lets you bid when logged in" do
        log_in  # Implemented somewhere else.
        visit auction_path
        place_bid
        bid_should_be_accepted
      end
    
      it "doesn't let you bid when not logged in" do
        visit item_path
        place_bid
        bid_should_be_rejected
      end
    
      def auction_path
        raise "Implement me."
      end
    
      def place_bid
        fill_in "Bid", with: 123
        click_button "Place bid"
      end
    
      def bid_should_be_accepted
        page.should have_content("OK! :)")
      end
    
      def bid_should_be_rejected
        page.should have_content("NO! :(")
      end
    end
    

    The only template method here is auction_path . The shared example makes sure, by raising, that it’s overridden in your concrete specs.

  • 相关阅读:
    远程诊断DoIP
    基于linux内核包过滤技术的应用网关
    Boost内存池使用与测试
    C++ 编程规范
    大象——Thinking in UML
    C++ 创建类时常考虑的问题
    SLIP—串行线路上传输数据报的非标准协议
    神秘的程序员——编程的乐趣
    Bad Smell (代码的坏味道)
    模式与软件架构——软件架构的非功能特征
  • 原文地址:https://www.cnblogs.com/goody9807/p/5481354.html
Copyright © 2011-2022 走看看