簡體   English   中英

如何使用 rspec 測試控制器中的所有路由

[英]how to test all routes in controller with rspec

我試圖限制我的應用程序中的一些控制器在任何操作之前都需要登錄。 我知道如何實現它,但不知道如何在 rspec 中為它編寫好的測試。

例如,如果我想限制我的用戶控制器的每個操作都需要登錄,我可以進行如下測試:

描述“授權”做

describe "for non-signed-in users" do
  let(:user) { FactoryGirl.create(:user) }

  describe "in the Users controller" do

    describe "visiting the index page" do
      before { visit users_path }
      it { should have_selector('title', text: 'Log In') }
    end

    describe "visiting the edit page" do
      before { visit edit_user_path(user) }
      it { should have_selector('title', text: 'Log In') }
    end

    describe "submitting to the update action" do
      before { put user_path(user) }
      specify { response.should redirect_to(login_path) }
    end

     describe "submitting a DELETE request to the Users#destroy action" do
      before { delete user_path(user) }
      specify { response.should redirect_to(root_path) }        
    end

....etc.....

  end
end

我是否需要為我要測試的每個控制器指定所有 7 個靜態路由? 看起來效率很低。 有沒有辦法說“在訪問任何用戶路由響應之前應該重定向到 login_path”?

我在嘗試列出然后測試我所有應用程序路由的 500 個錯誤時也有類似的擔憂,而且我不想手動逐個添加每個路由(我有 150 個左右)。

我在命令rake routes鏡像了代碼,並使用ActionDispatch::Routing::RouteWrapper以及Rails.application.routes.routes列出它們。

包裝器提供了一種簡單的方法來檢查路由的控制器、動詞和動作是什么。 從那里,您只需要過濾要檢查的路由,並在對每個路由進行測試時對其進行迭代。

context 'all routes' do
    let(:all_app_routes) do
      Rails.application.routes.routes.collect do |route|
        ActionDispatch::Routing::RouteWrapper.new route 
      end.reject(&:internal?)
    end
    context 'in the Users controller' do
      let(:users_controller_routes) do
        all_app_routes.select { |route| route.controller == 'users' }
      end

      it 'all routes should redirect to login' do
        users_controller_routes.each do |route|
          begin
            # reconstruct the path with the route name
            # I did not test the line below, I personnaly kept using get('/' << route.name) as my case was to test the index pages only.
            # but you get the idea: call your http route below (http.rb, net/http, ...)
            send(route.verb, '/' << route.name)
            # will produce something like : get('/users/')

            # test it does indeed redirect
            expect(response.status).to eq(302)
            expect(response.body).to include?('my_redirect_location')

            # you could also continue further testing
            follow_redirect!
            expect(response.body).to include('<div id="login">')
          rescue Exception
            next
            # or fail test depending on what you want to check
            # I had the case of abstract method in controllers that raised exception
          end
        end
      end
    end
  end

我個人僅使用此代碼來測試索引方法( select {|route| route.action =='index' }... ),因為批量測試 create/destroy/new/edit 被證明太困難了(不同需要的參數每個時間)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM