2011-02-12 102 views
18

我有一些控制器設置這樣一個永久的簽署餅乾一些值的動作:如何測試cookies.permanent.signed在Rails 3中

 

def some_action 
    cookies.permanent.signed[:cookie_name] = "somevalue" 
end 
 

而且在一些功能測試,我想測試如果cookie設置正確起訴這樣的:

 

test "test cookies" do 
    assert_equal "somevalue", cookies.permanent.signed[:cookie_name] 
end 

 

然而,當我運行測試,我得到了以下錯誤:

 

NoMethodError: undefined method `permanent' for # 
 

如果我只嘗試:

 

test "test cookies" do 
    assert_equal "somevalue", cookies.signed[:cookie_name] 
end 

 

我得到:

 

NoMethodError: undefined method `signed' for # 
 

如何測試簽名的cookies在Rails 3的?

回答

2

問題(至少在表面上)是在功能測試(ActionController :: TestCase)的上下文中,「cookies」對象是哈希,而當您使用控制器時,它是一個ActionDispatch: :Cookie :: CookieJar對象。所以我們需要將它轉換爲CookieJar對象,以便我們可以使用它上面的「signed」方法將它轉換爲SignedCookieJar。

你可以把下面的內容功能測試(GET請求後),以餅乾從哈希轉換爲CookieJar對象

@request.cookies.merge!(cookies) 
cookies = ActionDispatch::Cookies::CookieJar.build(@request) 
+0

我有完全相同的問題。我正在使用測試單元。我不明白如何使用你的2班輪。我嘗試了不同的排列,但沒有任何工作。你能舉一個更徹底的例子來說明如何使用它。 – allesklar 2011-03-03 08:22:41

8

在軌道3的ActionControlller :: TestCase的,你可以設置簽署永久餅乾在像這樣的請求對象 -

@request.cookies.permanent.signed[:foo] = "bar" 

並從控制器採取的行動返回簽署Cookie可以由這樣

測試

請注意,我們需要設置簽名cookie jar.signed[:foo],但請閱讀未簽名的cookie jar[:foo]。只有這樣我們才能得到cookie的加密值,需要在assert_equal中進行比較。

+0

太棒了!我只是使用:`@ request.cookie_jar.signed [:foo] ='bar'` – 2012-02-02 16:18:05

18

我遇到了這個問題,同時谷歌搜索類似問題的解決方案,所以我會在這裏發佈。我希望在測試控制器操作之前在Rspec中設置一個簽名的cookie。以下工作:

jar = ActionDispatch::Cookies::CookieJar.build(@request) 
jar.signed[:some_key] = "some value" 
@request.cookies['some_key'] = jar[:some_key] 
get :show ... 

請注意,以下沒有工作:

# didn't work; the controller didn't see the signed cookie 
@request.cookie_jar.signed[:some_key] = "some value" 
get :show ... 
+0

剛剛碰到這個,它完美地解決了我的問題,但作爲一個重要附錄,我必須更改: @request。 cookies [:some_key] 至: @ request.cookies [「some_key」] – Atiaxi 2011-09-09 11:03:51

+0

Great balexand。我希望你能給你10個大拇指。 – allesklar 2011-12-08 15:29:35

0

的問題也顯得你的測試。

以下是我用於TDD的一些代碼和測試,您可以通過將params值傳遞給視圖來設置cookie的值。

功能測試:

test "reference get set in cookie when visiting the site" do 
    get :index, {:reference => "121212"} 
    refute_nil cookies["reference"] 
end 

SomeController:

before_filter :get_reference_code 

的ApplicationController:

def get_reference_code 
    cookies.signed[:reference] ||= params[:reference] 
end 

注意,refute_nil線,餅乾是一個字符串...這是一件事那也使得這個測試沒有通過,在cookies[:reference]中放了一個符號,測試沒有像那樣,所以我沒有那樣做。

7

看着處理這個Rails代碼後,我創建了這個測試助手:

def cookies_signed(name, opts={}) 
    verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze]) 
    if opts[:value] 
     @request.cookies[name] = verifier.generate(opts[:value]) 
    else 
     verifier.verify(cookies[name]) 
    end 
    end 

添加這test_help.rb,那麼你可以設置一個簽署的cookie:

cookies_signed(:foo, :value => 'bar') 

而且隨着閱讀:

cookies_signed(:foo) 

一個有點hackish也許,但它的工作對我來說。