paypal - 如何在 Rails 2.3 应用程序中使用 TestUnit 配置 PayPal Express Checkout 的集成测试

标签 paypal integration-testing ruby-on-rails-2 testunit

我们正在添加 PayPal Express Checkout 作为一个选项,用于 checkout 在 Rails 2.3.18 上运行的电子商务应用程序。我已经为我的自定义 PayPal::Merchant::ExpressCheckout 模块编写了代码并进行了一些单元测试,但是我无法理解如何正确地模拟或 stub Controller 方法以便我可以编写集成测试。

我面临的一个问题是,所有 PayPal API 调用都是针对同一个端点 URI,在 POSTed 数据中只有一个操作参数来区分我们正在调用的操作。虽然我已成功设置 FakeWeb 以在我的单元测试中模拟来自 PayPal API 的正确 XML 响应,但在某些集成场景中我需要能够处理背靠背 API 请求。有没有办法告诉 FakeWeb 根据发布的数据做出不同的响应?或者,有没有办法让 FakeWeb 在拦截第一个请求后触发回调方法,以便我可以设置下一个请求?

另一个问题是如何模拟到 PayPal 的重定向。现在,用户单击我们网站上的使用 PayPal 结帐按钮,将他们重定向到我的 ExpressCheckoutsController 上的 setup 方法,该方法获取 token 并设置结帐 URL,然后将用户重定向到那里。我需要在集成测试中模拟两种场景: 1.用户正确提交表单并发送到我的返回URL 2. 用户取消并发送到我的取消网址 有没有一种方法可以在不重写测试文件中的整个 ExpressCheckoutsController 类的情况下做到这一点?

以防万一,我们使用 paypal-sdk-merchant gem。我们的测试环境使用以下 gem:

group :test do
  gem 'autotest-rails', '4.1.0'
  gem 'ZenTest', '< 4.6'
  gem 'fakeweb', '1.2.6'
  gem 'mocha', '0.9.4'
  gem 'quietbacktrace', '0.1.1'
  gem 'factory_girl', '1.2.0'
  gem 'thoughtbot-shoulda', '2.10.2', :require => 'shoulda'
  gem 'nokogiri', '1.5.6'
  gem 'webrat', '0.4.4'
end

更新

我能够通过使用 Mocha stub 我的自定义 ExpressCheckout 模块的 express_checkout_url 方法来解决重定向问题,以便它简单地重定向到 return取消 操作。

PayPal::Merchant::ExpressCheckout.any_instance.stubs(:express_checkout_url).returns(return_order_express_checkout_path)

最佳答案

我了解到 FakeWeb 支持 rotating responses ,虽然这有助于某些集成测试步骤,但我仍然遇到 GetExpressCheckoutDetails API 方法在 SetExpressCheckout 之间被调用的次数不确定的情况DoExpressCheckoutPayment 调用,具体取决于其他几个因素。在深入研究了很多 PayPal::SDK::Core 库之后,我并没有试图弄清楚我需要伪造多少响应,而是在集成测试中使用了这个辅助方法类:

def stub_express_checkout
  api = PayPal::SDK::Merchant::API.new

  PayPal::Merchant::ExpressCheckout.any_instance.stubs(:express_checkout_url).returns(return_order_express_checkout_path)

  FakeWeb.register_uri(
    :post,
    api.service_endpoint,
    :content_type => "application/xml",
    :status => ["200", "OK"],
    :body => ""
  )

  PayPal::Merchant::ExpressCheckout.any_instance.stubs(:set_express_checkout).returns(
    PayPal::SDK::Merchant::DataTypes::SetExpressCheckoutResponseType.new(api.format_response({
      :response => FakeWeb.response_for(:post, api.service_endpoint).tap { |resp| 
        resp.instance_variable_set("@body", File.read(Rails.root.join("test/fixtures/express_checkout/success/set.xml")))
      }
    })[:data])
  )

  PayPal::Merchant::ExpressCheckout.any_instance.stubs(:get_express_checkout).returns(
    PayPal::SDK::Merchant::DataTypes::GetExpressCheckoutDetailsResponseType.new(api.format_response({
      :response => FakeWeb.response_for(:post, api.service_endpoint).tap { |resp| 
        resp.instance_variable_set("@body", File.read(Rails.root.join("test/fixtures/express_checkout/success/get.xml")))
      }
    })[:data])
  )

  PayPal::Merchant::ExpressCheckout.any_instance.stubs(:do_express_checkout).returns(
    PayPal::SDK::Merchant::DataTypes::DoExpressCheckoutPaymentResponseType.new(api.format_response({
      :response => FakeWeb.response_for(:post, api.service_endpoint).tap { |resp| 
        resp.instance_variable_set("@body", File.read(Rails.root.join("test/fixtures/express_checkout/success/do.xml")))
      }
    })[:data])
  )

  FakeWeb::Registry.instance.uri_map[FakeWeb::Registry.instance.send(:normalize_uri, api.service_endpoint)] = {}
end

这很丑陋,我不喜欢依赖这么多内部 PayPal::SDK::Core 方法来 stub 我的模块方法,但在我尝试的 2 打方法中,这是最终起作用的方法。

关于paypal - 如何在 Rails 2.3 应用程序中使用 TestUnit 配置 PayPal Express Checkout 的集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19546520/

相关文章:

java - PayPal 的未知主机异常

php - PayPal IPN 返回 "INVALID",即使付款已处理

entity-framework - 如何为测试目的创建 EF codefirst 类的分离克隆?

integration-testing - 集成测试最佳实践

ruby-on-rails - 我如何检查 ruby​​ on rails 2 中的对象是否为空?

ruby - 在 Monterey 12.0.1 上安装 RVM 1.8.7 失败

php - Paypal API,Curl 不返回任何输出

java - 如何编写使用Azure SDK的测试?

ruby-on-rails - Rails 在循环中呈现部分

paypal - 获取账单信息快速结账