2013-12-21 61 views
2

我在我的路由中有一個約束,只允許發送一個jjax請求。 如何用rspec測試這個? 特別是什麼測試會顯示/日程安排是可路由的,但僅限於AJAX。如何使用rspec/rails測試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 
+1

你在問什麼?你是否建議這個測試應該失敗?你需要幫助寫其他測試?如果是這樣,你在尋求什麼樣的測試幫助? –

+0

是的,對不起。我要求一個可以測試的測試。像某種'{:ajax_get =>'/schedules'}.should be_routable' – mazlix

回答

2

試試這個
get "/schedules",format: :xhr
response.should be_ok

+2

這給了我一個錯誤「ArgumentError:錯誤的參數數量(2爲1)」 – mazlix

2

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

的時間表控制器SPE c爲你的目的工作?瞭解這不是直接測試,如果該路線是「可路由」。

查看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

要測試你的「/時間表」 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'/ schedule'路線。

由於RSpec的護欄在路由規範測試AJAX路線不提供任何幫手,你將不得不間接地測試它在控制器規格,如:

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

既然你有測試AJAX路由是否正在處理您的控制器規範,它會幫助在您的路由規範中留下評論,說明AJAX請求預計可路由,並通過控制器規範進行測試。有一個路由規範檢查'/ schedules'的非AJAX請求不應該是可路由的,除非配合另一個檢查'/ schedules'的AJAX請求應該可路由的斷言。沒有辦法通過路由規範來測試,下一個最佳選擇是留下評論並通過控制器規範間接測試。

+0

這似乎應該是一個很好的測試,但它失敗了......''失敗/錯誤:{:get =>'/ schedules',格式:: xhr}。應該是可路由的 期望{:get =>「/ schedules」,:format =>:xhr} ' – mazlix

+0

route_to和be_routable匹配器忽略了除選項哈希中的第一個鍵值對以外的所有內容,所以這不起作用。請參閱:「匹配?」方法: https://github.com/rspec/rspec-rails/blob/master/lib/rspec/rails/matchers/routing_matchers.rb –

+0

@SteveRowley是對的。第二個參數被忽略,不會被處理。我提供的代碼實際上是檢查正常路線。它看起來沒有提供匹配器來檢查路由是否適用於AJAX。將改變我的答案,並提供其他建議作爲解決方法。 – Gjaldon

1

我在Steve Rowley的答案中寫了一個問題的答案,在我看來,這裏也適用相同的建議。問問你自己 - 我想測試什麼?您是否測試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 

東西說實話,在這種特殊情況下,很難讓我看到太多的理由甚至這些測試打擾,但是這就是我想測試你要測試的內容。

1

我通過對ActionDispatch::Request類的方法xhr?進行了存根測試來測試我的規範示例。

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