Ruby on rails 如何制作ActiveResource集成测试用例?

Ruby on rails 如何制作ActiveResource集成测试用例?,ruby-on-rails,activeresource,Ruby On Rails,Activeresource,我正在使用Rails开发一个内部API,我正在考虑使用ActiceResource来访问它。我想使用ActiveResource制作集成测试用例(即向测试环境中的控制器发出http请求),但不知道如何设置测试用例 在正常的集成测试用例中,您使用get/post方法向自己的应用程序发送请求。不知何故,我应该告诉ActiceResource连接到我的应用程序,而不是建立真正的http连接 我看到的所有ActiveResource测试示例都使用mock。我希望避免这种情况,而是对控制器代码运行测试。我

我正在使用Rails开发一个内部API,我正在考虑使用ActiceResource来访问它。我想使用ActiveResource制作集成测试用例(即向测试环境中的控制器发出http请求),但不知道如何设置测试用例

在正常的集成测试用例中,您使用get/post方法向自己的应用程序发送请求。不知何故,我应该告诉ActiceResource连接到我的应用程序,而不是建立真正的http连接

我看到的所有ActiveResource测试示例都使用mock。我希望避免这种情况,而是对控制器代码运行测试。我正在使用Rails 5和Minitest

下面是显然不起作用的测试代码。如果我尝试运行它,它将给出一个错误:

require 'test_helper'

module MyApp
  class User < ActiveResource::Base
    self.site = 'http://www.example.com'
  end
end

class UserFlowsTest < ActionDispatch::IntegrationTest
  test "should get index" do
    users = MyApp::User.all

    assert_response :success
  end
end


▶ rails test test/integration/user_flows_test.rb
NoMethodError: undefined method `response_code' for nil:NilClass
    actionpack (5.2.1) lib/action_dispatch/testing/assertions/response.rb:81:in `generate_response_message'
    actionpack (5.2.1) lib/action_dispatch/testing/assertions/response.rb:31:in `assert_response'
    test/integration/user_flows_test.rb:13:in `block in <class:UserFlowsTest>'
需要“测试助手”
模块MyApp
类用户
我找到了一种方法。这是一个黑客,但似乎工作得很好

在集成测试中,Rails定义了get/post/etc helpers方法,然后在测试用例中使用这些方法连接Rails应用程序。为了使ActiveResource使用helpers方法而不是发出真正的HTTP请求,我使用了一个修补的AR请求方法。我使用全局变量发送当前测试用例并访问帮助器方法

# Include this in test_helper.rb into ActiveSupport::TestCase class
module ActiveResourceMonkeyPatching
  module ::ActiveResource
    # We need to monkey patch AR:Connection to use IntegrtionTest helper
    # methods (get, post, ...) instead of Net:Http
    class Connection
      private

      # Makes a request to the remote service.
      def request(method, path, *arguments)
        result = ActiveSupport::Notifications
                .instrument('request.active_resource') do |payload|
          payload[:method] = method
          payload[:request_uri] =
            "#{site.scheme}://#{site.host}:#{site.port}#{path}"
          payload[:result] =
            $test.send(method,
                      path,
                      { params: arguments.first, headers: arguments.last }) &&
            $test.response
        end
        handle_response(result)
      rescue Timeout::Error => e
        raise TimeoutError.new(e.message)
      rescue OpenSSL::SSL::SSLError => e
        raise SSLError.new(e.message)
      end
    end

    # Lets also predefine site so we don't need to configure those in test cases
    class Base
      self.site = 'http://www.example.com'
    end
  end

  # We also monkey patch IntegrationTest to set the '$test' global variance which is
  # needed in ActiveResource
  class ActionDispatch::IntegrationTest
    def setup
      $test = self
      super
    end
  end
end
自从我开始monkey补丁以来,我还添加了一些来传递全局变量,并设置dummy
site
属性。实际的测试用例很简单,请参见下文。由于我们将此作为正常的集成测试运行,所以用户模型中的所有修复程序都像往常一样加载

require 'test_helper'

module MyApp
  class User < ActiveResource::Base
  end
end

class UserFlowsTest < ActionDispatch::IntegrationTest
  test "should get index" do
    users = MyApp::User.all

    assert_response :success
  end
end
需要“测试助手”
模块MyApp
类用户
这是一个hack:)使用monkey补丁意味着上述解决方案可以与当前版本的Rails和ActiveResource一起工作,并且在更新这些版本时将失败。如果有人找到其他方法来解决这个问题,我很想知道