Ruby 我如何测试这个特殊的方法?

Ruby 我如何测试这个特殊的方法?,ruby,rspec,nokogiri,open-uri,Ruby,Rspec,Nokogiri,Open Uri,我有以下方法负责请求URL并返回它的Nokogiri::HTML文档。此方法检查是否定义了代理,如果定义了代理,它将调用OpenURI的open,使用或不使用代理选项 实施 require 'open-uri' require 'nokogiri' class MyClass attr_accessor :proxy # .... def self.page_content(url) if MyClass.proxy proxy_uri = URI.par

我有以下方法负责请求URL并返回它的
Nokogiri::HTML
文档。此方法检查是否定义了代理,如果定义了代理,它将调用
OpenURI
open
,使用或不使用代理选项

实施

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
我不知道应该如何编写测试来证明以下内容:

  • 定义代理时,OpenURI发出的请求实际上使用代理信息
  • 未定义代理时,将建立常规的非代理连接
  • 以下是我为测试准备的开始

    describe MyClass, :vcr do
    
      describe '.proxy' do
        it { should respond_to(:proxy) }
      end
    
      describe '.page_content' do
        let(:url) { "https://google.com/" }
        let(:page_content) { subject.page_content(url) }
    
        it 'returns a Nokogiri::HTML::Document' do
          page_content.should be_a(Nokogiri::HTML::Document)
        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
    
        context 'when not using a proxy' do
          # ???
          xit 'should not set open-uri proxy properties' do
          end
        end
    
      end
    
    end
    

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

    然后,您至少要在
    open
    上设置一个期望值,根据它是哪个测试,使用或不使用
    :proxy
    选项调用它。除此之外,您还可以选择是否存根并设置方法中涉及的各种其他调用的期望值,包括
    URI.parse
    Nokogiri::HTML

    有关建立双倍测试和设置期望值的信息,请参阅。如果要使用部分存根方法,请特别注意
    和_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
    的存根很棘手。请参阅以获取解释。

    在您的实现中,
    open
    指的是什么?@PeterAlfvin
    open
    由OpenURI提供。我将对代码进行注释,以明确说明这一点。您是想在测试中实际打开URI并调用Nokogiri,还是只想确保您正在进行这些调用(即使用存根)?@PeterAlfvin我不知道这个问题的答案。对不起,这对我来说很新鲜。我想答案是我只是想确定我在打那些电话。但我不知道是否应该通过存根进行访问。我已更新了我的问题,以显示
    代理的
    属性访问器
    。你的第一段很有意义;非常感谢。不幸的是,你所说的关于使用mock和
    以及_call_original
    的话毫无意义。实际上,我已经阅读了文档并浏览了rspec手册,但我在理解要模拟哪些对象时遇到了困难,如果可能的话,我希望看到代码。谢谢大家!
    attr_accessor
    为实例变量提供setter和getter。您正在通过同名的类方法引用
    代理
    。您还将
    页面内容
    定义为
    主题。页面内容(…)
    ,但
    主题
    隐含为
    MyClass
    的新实例,并且没有
    页面内容
    实例方法。一般来说,如果你开始执行你的规范,RSpec会告诉你哪里出了问题,如果你陷入困境,你可以在这里得到帮助。