如何使用rspec / rails测试AJAX请求的路由

时间:2013-12-21 19:38:55

标签: ruby-on-rails ajax testing rspec routing

我的路由中有一个约束,只允许路由ajax请求。 如何使用rspec进行测试? 具体来说,测试会显示/ schedules是可路由的,但只能来自AJAX。

的routes.rb

  class OnlyAjaxRequest
    def matches?(request)
      request.xhr?
    end
  end

  resources :schedules, :constraints => OnlyAjaxRequest.new

我目前正在通过以下部分测试,以表明正常的GET请求不可路由,但我想知道如何测试AJAX GET请求是否可路由。

规格/路由/ schedules_routing_spec.rb

require 'spec_helper'

describe "GET /schedules" do
    it "returns http failure to non AJAX request" do
      {:get => '/schedules'}.should_not be_routable
  end
end

5 个答案:

答案 0 :(得分:2)

试试这个 get "/schedules",format: :xhr
response.should be_ok

答案 1 :(得分:2)

xhr :get, :index
expect(response).to be_ok

在日程表控制器规范中为您的目的工作?了解这不是直接测试该路由是否“可路由”。

查看rspec-rails中的路由匹配器代码,似乎这些匹配器不支持额外的选项。后来我找到了这个答案:

How to test route constraints with rspec

这比我更好地解释了这一点。他们的建议是只测试你的约束类并相信Rails路由按预期工作。在Rails源代码中有一些块/对象约束的测试:

https://github.com/rails/rails/blob/master/actionpack/test/dispatch/routing_assertions_test.rb

由于您主要关注的是限制您将接受的请求类型,而您的其他测试验证这些限制是否按预期工作,说实话我会坚持使用控制器规范方法来测试快乐路径。如果你有更复杂的约束根据请求对象的属性匹配不同的路由,我可能会测试约束类本身,正如另一个答案所暗示的那样。

答案 2 :(得分:2)

要测试您的'/ schedule''AJAX路线,请尝试以下代码:

require 'spec_helper'

describe "GET /schedules" do
  it "returns http success for an AJAX request" do
    {:get => '/schedules', format: :xhr}.should be_routable
  end
end

事实证明,上面的代码不会像SteveRowley在其中一个答案中指出的那样有效。第二个参数被忽略,因此上面的代码只测试常规的get'/ schedules'路径。

由于rspec-rails没有提供任何帮助来测试路由规范中的AJAX路由,因此您将不得不在控制器规范中间接测试它,如:

xhr :get, :index
expect(response).to be_ok

由于您必须测试AJAX路由是否正在通过您的控制器规范,因此有助于在您的路由规范中留下注释,指出AJAX请求应该是可路由的,并且这是通过控制器规范进行测试的。有一个检查非AJAX请求'/ schedules'的路由规范不应该是可路由的,除非与另一个检查'/ schedules'的AJAX请求应该是可路由的断言配对,否则没有意义。无法通过路由规范测试,下一个最佳选择是留下评论并通过控制器规范间接测试。

答案 3 :(得分:1)

我写了回答史蒂夫罗利回答的问题的答案,我认为同样的建议适用于此。问问自己 - 我想测试什么?您是否正在测试Rails的路由DSL是否会应用所宣传的路由约束?在我看来,这不是你需要在你的应用程序中进行测试的东西。因此,您希望测试路由约束是否适用于xhr请求,但不适用于非xhr请求。

为此,您只需要对路由约束对象本身进行单元测试。像

这样的东西
describe OnlyAjaxRequest

  describe "#matches?" do

    subject { OnlyAjaxRequest.new.matches?(req) }

    context "xhr request" do
      let(:req) { double('request', :xhr? => true) }

      it { should be_true }
    end

    context "non-xhr request" do
      let(:req) { double('request', :xhr? => false) }

      it { should be_false }
    end
  end

end

老实说,在这种特殊情况下,我很难看到有太多理由去打扰这些测试,但这就是我测试你试图测试的内容。

答案 4 :(得分:1)

我通过隐藏类xhr?的方法ActionDispatch::Request测试了我的规范示例。

require 'rails_helper'

describe "GET /schedules" do
  it "routes to /schedules when request is an ajax request" do
    allow_any_instance_of(ActionDispatch::Request).to receive(:xhr?).and_return(true)
    expect(get: '/schedules').to be_routable
  end
end