我该如何测试这种特殊方法?

时间:2013-08-11 03:51:07

标签: ruby rspec nokogiri open-uri

我有以下方法负责请求URL并返回它的Nokogiri::HTML文档。此方法检查是否已定义代理,如果已定义,则会在有或没有代理选项的情况下调用OpenURI的{​​{1}}。

实施

open

我不知道如何编写证明以下内容的测试:

  1. 定义代理时,请求OpenURI实际使用代理信息
  2. 未定义代理时,将建立常规非代理连接
  3. 这是我想出的测试开始。

    require 'open-uri'
    require 'nokogiri'
    
    class MyClass 
      attr_accessor :proxy
    
      # ....
    
      def self.page_content(url)
        if MyClass.proxy
          proxy_uri = URI.parse(MyClass.proxy)
          Nokogiri::HTML(open(url, :proxy => proxy_uri)) # open provided by OpenURI
        else
          Nokogiri::HTML(open(url)) # open provided by OpenURI
        end
      end
    end
    

1 个答案:

答案 0 :(得分:3)

首先,您需要安排proxy方法在一个测试用例中返回代理而不在另一个测试用例中。如果有代理的“setter”方法,您可以使用它,否则您可以存根proxy方法。

然后,至少,您希望在open上设置一个期望,即使用或不使用:proxy选项,它将被调用,具体取决于它是哪个测试。除此之外,您还可以选择是否存储和设置方法中涉及的各种其他调用的期望,包括URI.parseNokogiri::HTML

有关建立测试双打和设置期望的信息,请参阅https://github.com/rspec/rspec-mocks。如果要使用部分存根方法,请特别注意and_call_original选项。

更新:这里有一些代码可以帮助您入门。这适用于非代理方法。我已经离开了你的代理案例。另请注意,这使用了“部分存根”方法,您仍然最终调用外部gem。

require 'spec_helper'

describe MyClass do

  describe '.proxy' do         # NOTE: This test succeeds because of attr_accessor, but you're calling a MyClass.proxy (a class method) within your page_content method
    it { should respond_to(:proxy) }
  end

  describe '.page_content' do
    let(:url) { "https://google.com/" }
    let(:page_content) { MyClass.page_content(url) } # NOTE: Changed to invoke class method

    context 'when not using a proxy' do

      before {allow(MyClass).to receive(:proxy).and_return(false)} # Stubbed for no-proxy case

      it 'returns a Nokogiri::HTML::Document' do
        page_content.should be_a(Nokogiri::HTML::Document)
      end

      it 'should not set open-uri proxy properties' do
        expect(MyClass).to receive(:open).with(url).and_call_original  # Stubbing open is tricky, see note afterwards
        page_content
      end
    end
        # How do i test this method actually uses a proxy when it's set vs not set?
    context 'when using a proxy' do
      # ???
      xit 'should set open-uri proxy properties' do
      end
    end

  end

end

open的结账很棘手。有关说明,请参阅How to rspec mock open-uri?