【问题标题】:Having trouble with WebMock, not stubbing correctly使用 WebMock 时遇到问题,无法正确存根
【发布时间】:2014-12-26 21:58:34
【问题描述】:

Ruby 1.9.3、RSpec 2.13.0、WebMock 1.17.4、Rails 3

我正在为公司应用程序编写测试。有问题的控制器显示客户已拨电话的表格,并允许排序/过滤选项。

编辑 测试失败,因为在我当前的设置下,路径没有呈现,因为 recorder_server 要么没有在本地运行,要么没有正确设置。也请帮忙。

A Errno::ECONNREFUSED occurred in recordings#index:
Connection refused - connect(2)
/usr/local/lib/ruby/1.9.1/net/http.rb:763:in `initialize'

-------------------------------
Request:
-------------------------------
* URL       : http://www.recorder.example.com:8080/recorded_calls
* IP address: 127.0.0.1
* Parameters: {"controller"=>"recordings", "action"=>"index"}
* Rails root: /var/www/rails/<repository>
  1. 发出调用后,其数据将加入一个 xml 文件,由外部 API 创建,称为 Recorder
  2. RecordingsController 获取 xml 文件,并将其解析为哈希。
  3. 当您访问相关路径时,您会看到散列的结果 - 已发出调用、它们的属性和排序/过滤参数的表。

这是我目前的规格。

require 'spec_helper'
include Helpers

feature 'Exercise recordings controller' do
  include_context "shared admin context"

  background do
    canned_xml = File.open("spec/support/assets/canned_response.xml").read
    stub_request(:post, "http://recorder.example.com:8080/recorder/index").
      with(body: {"durations"=>["1"], "durations_greater_less"=>["gt"], "filter_from_day"=>"29", "filter_from_hour"=>"0", "filter_from_minute"=>"0", "filter_from_month"=>"12", "filter_from_year"=>"2014", "filter_prefix"=>true, "filter_to_day"=>"29", "filter_to_hour"=>"23", "filter_to_minute"=>"59", "filter_to_month"=>"12", "filter_to_year"=>"2014"}, # "shared_session_id"=>"19f9a08807cc70c1bf41885956695bde"},
           headers: {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
      to_return(status: 200, body: canned_xml, headers: {})
    uri = URI.parse("http://recorder.example.com:8080/recorder/index")
    visit recorded_calls_path
  end

  scenario 'show index page with 1 xml result' do
    #page.save_and_open_page
    expect(title).to eq("Recorded Calls")
  end
end

这里是 RecordingsController

class RecordingsController < ApplicationController
  # before_filter options
  def index
    test_session_id = request.session_options[:id]
    #Make request to recording app for xml of files
    uri = URI.parse("http://#{Rails.application.config.recorder_server}:#{Rails.application.config.recorder_server_port}/recorder/index")
    http = Net::HTTP.new(uri.host, uri.port)
    xml_request = Net::HTTP::Post.new(uri.request_uri)
    xml_request_data = Hash.new
    # sorting params
    xml_request_data[:shared_session_id] = request.session_options[:id]
    xml_request.set_form_data(xml_request_data)
    response = http.request(xml_request)
    if response.class == Net::HTTPOK
      @recordings_xml = XmlSimple.xml_in(response.body)
      @recordings_sorted = @recordings_xml["Recording"].sort { |a,b| Time.parse("#{a["date"]} #{a["time"]}") <=> Time.parse("#{b["date"]} #{b["time"]}") } unless @recordings_xml["Recording"].nil?
    else @recordings_xml = Hash.new
    end
  end
  # other defs
end

非常感谢任何和所有建议。谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby rspec controller webmock


    【解决方案1】:

    我如何配置 WebMock

    B-Seven 和一串 cmets 的帮助下,我正在回答我自己的问题。逐个文件,我将列出为了正确使用 WebMock 所做的更改。

    1. 将 WebMock 添加到 Gemfile 下的 group :test, :development
      • bundle install 解决依赖关系
      • 我当前的设置包括 Ruby 1.9.3、Rails 2.13.0、WebMock 1.17.4
    2. 设置 spec_helper.rb 以禁用“真实 HTTP 连接”。 (这是后来在这个令人费解的过程中收到的回溯错误。)据我了解,这允许所有“真实连接”转换为 localhost 连接并离线工作......这很好,因为理想情况下,我不希望外部应用的服务器同时运行。

      require 'webmock/rspec'
      WebMock.disable_net_connect!(allow_localhost: true)
      
    3. 在我的test.rb 环境文件中,recorder_serverport 的配置已被注释掉...如果未注释,控制器将引发异常,说明未初始化的常量。我使用测试服务器/端口(用公司名称代替example)作为规范存根的布局。

    4. recordings_controller_spec.rb 中,我已经想出了如何制作一个固定的 XML 响应。通过上述这些更改,我的规范能够正确地存根外部辅助应用程序上的响应,并使用此类响应来正确呈现与正在测试的控制器关联的视图。

      require 'spec_helper'
      include Helpers
      
      feature "Exercise recordings_controller" do
        include_context "shared admin context"
      
        # A background is currently not used, because I have 3 scenario types... No xml
        # results, 1 result, and 2 results. I will later DRY this out with a background,
        # but the heavy lifting is over, for now.
      
        scenario "show index page with 1 xml result" do
          canned_xml_1 = File.open("spec/support/assets/canned_response_1.xml").read
          stub_request(:post, "http://recorder.example.com:8080/recorder/index").
            with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
            to_return(status: 200, body: canned_xml_1, headers: {})
          uri = URI.parse("http://recorder.example.com:8080/recorder/index")
          visit recorded_calls_path
          title.should == "Recorded Calls"
          page.should have_content("Search Results")
          page.should have_content("Inbound", "5551230000", "175", "December 24 2014", "12:36:24", "134")
        end
      
      end
      

    有帮助的建议/资源

    【讨论】:

      【解决方案2】:

      你为什么要存根本地主机?我想你想

      stub_request(:get, "http://#{Rails.application.config.recorder_server}:#{Rails.application.config.recorder_server_port}/recorder/index").
      

      【讨论】:

      • 谢谢。 test.rb 文件已将这些配置注释掉。我需要在存根之前在该文件中定义它们吗?
      • 看起来配置设置正确。它正在向 example.com 发出请求,这很好。所以你应该 stub_request example.com 或Rails.application.config.recorder_server。我认为后者更好。
      • 但是,WebMock 似乎无法正常工作。看来您需要使用WebMock.disable_net_connect!。您使用的是哪个版本的 WebMock?
      • 看来WebMock版本还可以。在运行规范之前,您需要使用 disable_net_connect!stub_request。首先disable_net_connect! 它应该告诉你它想要发出的HTTP 请求。然后你就会确切地知道要存根什么。
      • spec_helper.rb,我有WebMock.disable_net_connect!(allow: "http://recorder.example.com:8080")。即使遵循建议的stub_request,我也收到A WebMock::NetConnectNotAllowedError occurred in recordings#index: Real HTTP connections are disabled. 错误。我的规范背景中有存根请求。仅使用 WebMock 就可以实现我想要实现的目标吗?
      猜你喜欢
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多