2016-02-09 28 views
1

我創建了一個RSpec規範來測試一個POST#創建行動正常工作:我應該寫什麼測試來測試僅限管理員功能的用戶驗證?

describe "POST #create" do 
    it "creates a career" do 
    expect { 
     post "/careers/", career: attributes_for(:career) 
    }.to change(Career, :count).by 1 
    end 
end 

上面的代碼工作正常。當我創建另一個測試以僅允許角色爲「admin」的用戶時,會發生此問題。我是否需要創建一個新用戶,登錄它們,然後運行上述測試?我是否需要爲所有將來基於用戶角色的限制進行測試?

是否有另一種方法來做這種類型的測試? 1)只測試一下create方法是否工作,2)只允許具有「admin」角色的用戶訪問GET#new和POST #create方法?

+0

任何人都可以創建一個職業,或只有管理員? –

+0

我想只有管理員創建職業。 –

+1

@Ankit - 你有這個工作嗎? – jvillian

回答

1

當你的功能完全開發,你會希望有以下測試:在管理員創建一個職業

  • 一個幸福道測試
  • 在其中一個非管理員試圖創建一個職業,但不能這樣做
  • 可能另一個未登錄的用戶試圖創造一個職業,但被阻止這樣做(是否要這取決於是否必須編寫不同的代碼來處理未登錄和已登錄的非管理員用戶)和
  • 可能對管理員創建職業的不同場景進行其他測試。

有一個完整的快樂路徑測試的想法是測試中最基本的模式之一,但我不知道它有一個名稱,除了被術語「快樂路徑」所暗示外, 。

它看起來像你在做TDD。大!爲了從現在的位置到上面的測試列表,下一個要寫的測試是未登錄用戶無法創建職業的測試。爲了使兩個測試同時通過,您需要更改第一個測試以登錄管理員。如果你需要更多成功創建職業生涯的測試(第4項),是的,你也需要登錄管理員。

旁註:

  • 除非你已經擁有了它,我會寫你的幸福路徑規範作爲控制器的規格,但作爲一個功能規範(驗收測試),所以您指定的UI和集成的重要部分 - 測試整個堆棧。您的失敗身份驗證規範可能會作爲控制器規格工作,但您可能會認爲當用戶至少沒有其中一種方案的權限時,您需要接受測試UI。

  • 我真的不喜歡expect {}.to change的語法。它阻止您對發佈結果做出任何其他期望。在你的例子中,我希望HTTP響應狀態是200(response.should be_success)。正如我所說,雖然,我的第一個規格將是一個功能規格,而不是控制器規格。

+0

偉大的測試方法的意見!我對你的'expect {}。'改變'評論很感興趣。我試着只用一句話來表達一個期望。所以,如果一個「它」的聲明失敗了,那麼很明顯哪個期望沒有得到滿足。 – jvillian

+0

這是一個常見的做法,但[在我看來(http://stackoverflow.com/a/23550938/634576)產生有害的。 –

+0

感謝您的評論!有不同的觀點是很好的。而且,這是一個很好的提醒,這些東西,以便保持實用性。就個人而言,當我已經摺磨(或慢跑)的測試中,我把它作爲一個機會,思考爲什麼我的測試是折磨或緩慢。通常,潛在的潛在重新設計/重構。再次感謝。 – jvillian

0

所以,這是一個有趣的問題。是的,您應該確定(IMO)與目標方法/操作分開測試認證。其中每一個都構成一個功能單元,應該這樣測試。

在我目前的項目中,我喜歡PORO(我經常把它們放在一個名爲'managers'的目錄中,儘管我知道很多人更喜歡稱它們爲'services'),因爲它可以讓我分離功能並獨立進行測試。所以,我可能會喜歡的東西最終會:

# controllers/foo_controller.rb 
class FooController < ApplicationController 
    before_action :authenticate 

    def create 
    @results = FooManager.create(params) 
    redirect_to (@results[:success] ? my_happy_path : my_sad_path) 
    end 

    def authenticate 
    redirect_to unauthorized_path unless AuthenticationManager.authenticate(params, request) 
    end 
end 

# managers/foo_manager.rb 
class FooManager 
    class << self 

    def create(params) 
     # do a bunch of great stuff and return a hash (perhaps a 
     # HashWithIndifferentAccess, if you like) which will 
     # allow for evaluation of @results[:success] back in the 
     # controller. 
    end 

    end 
end 

# managers/authentication_manager.rb 
class AuthenticationManager 
    class << self 

    def authenticate(params, request) 
     # do a bunch of great stuff and return a boolean 
    end 

    end 
end 

有了這樣的做法,我可以很容易測試FooManager.createAuthenticationManager.authenticate(以及FooController.createFooController.authenticate路由)都獨立。萬歲!現在

,無論您的驗證框架或控制器方法是在單位層面正常運作,戴夫指出的非常好,是因爲預期整個系統是否表現一個單獨的問題。我和他一起進行高級集成測試,所以你很清楚「完成」是什麼樣的,你知道什麼時候該把它「運送」它!

相關問題