2009-12-01 32 views
1

我在lib目錄下創建了一個模塊,我可以在我的Rails應用程序中隨意調用它包含的各種方法(在添加include ModuleName之後),沒有任何問題。Rails - 爲什麼我不能在測試中使用我在模塊中創建的方法?

但是,當涉及到測試時,他們抱怨沒有這樣的方法存在。我試圖將模塊包含到我的測試助手中,但沒有運氣。任何人都可以幫忙

4) Error: 
test_valid_signup_redirects_user_to_spreedly(UsersControllerTest): 
NoMethodError: undefined method `spreedly_signup_url' for SpreedlyTools:Module 
    /test/functional/user_controller_test.rb:119:in `test_valid_signup_redirects_user_to_spreedly' 

module SpreedlyTools 
    protected 
    def spreedly_signup_url(user) 
    return "blahblah" 
    end 
end 

class ApplicationController < ActionController::Base 


    helper :all # include all helpers, all the time 
    protect_from_forgery # See ActionController::RequestForgeryProtection for details 
    include SpreedlyTools 
    .... 
end 

ENV["RAILS_ENV"] = "test" 
require File.expand_path(File.dirname(__FILE__) + "/../config/environment") 
require 'test_help' 

class ActiveSupport::TestCase 
    include SpreedlyTools 
    .... 
end 

require File.dirname(__FILE__) + '/../test_helper' 
require 'users_controller' 

# Re-raise errors caught by the controller. 
class UsersController; def rescue_action(e) raise e end; end 

class UsersControllerTest < ActionController::TestCase 
.... 

    def test_valid_signup_redirects_user_to_spreedly 
    get :new 
    assert_response :success 
    post :create, :user => {:first_name => "bobby", 
         :last_name => "brown", 
         :email => "[email protected]", 
         :email_confirmation => "[email protected]", 
         :password => "bobby1", 
         :password_confirmation => "bobby1"} 

    assert_response :redirect 
    user = assigns(:user) 
    assert_redirected_to SpreedlyTools.spreedly_signup_url(user) 

    end 
end 

回答

4

有幾個不同的錯誤在這裏。 首先,當您創建一個模塊並將模塊的內容混合到一個類中時,模塊內的方法將成爲該類本身的一部分。

這就是說,下面一行是沒有意義的

assert_redirected_to SpreedlyTools.spreedly_signup_url(user) 

假設你混合模塊合併到一個User類,你應該調用方法

assert_redirected_to User.new.spreedly_signup_url(user) 

還要注意new聲明。因爲你的include這個模塊進入類並且你沒有extend這個類,該方法成爲一個實例方法而不是一個類方法。

assert_redirected_to User.new.spreedly_signup_url(user) # valid 
assert_redirected_to User.spreedly_signup_url(user) # invalid 

由於這個原因,下面這一行沒有意義。

class ActiveSupport::TestCase 
    include SpreedlyTools 
    .... 
end 
+0

我的初衷並不是將這些方法作爲用戶類的一部分。相反,它們只是整個應用程序可用的一般方法。事後看來,它看起來應該重構,並且讓這種特殊的方法成爲一流的課程的一部分。但是,一般情況下,我應該能夠在我的任何測試中調用我在lib中的模塊中定義的方法,而無需添加任何包含/要求或其他代碼? – robodisco 2009-12-01 14:21:05

+2

只有遵循Ruby自動加載規則。 – 2009-12-01 15:34:03

+1

Re。第一條評論:我想補充一點,如果你有可能需要在你的應用程序的其他地方使用spreedly_signup方法,你可能需要考慮將它作爲一個單獨的模塊,並單獨測試SpreedlyTools ...沒有空間來解釋如何在評論中做到這一點,雖然...有關於stackoverflow解釋如何做到這一點的幾個很好的問題。 – btelles 2009-12-01 20:27:49

1

啊,這是一個微妙的問題,但容易糾正。而不是在測試套件中包含SpreedlyTools,而是要測試由包含SpreedlyTools的類創建的對象。

在Ruby中,您可能會發現Classes的工作方式與您認爲模塊工作的方式有很大關係。您可以通過定義類級別函數來使用它:

class SpreedlyTools 
    def self.spreedly_signup_url user 
    ... 
    end 
end 

SpreedlyTools.spreedly_signup_url user 

現在這會有意義。

模塊用於在代碼中混合其他類。但是,如果你只是想要隨時可用的通用工具,你真的想要課堂級別的功能。

+0

對不起,如果這已經在這裏回答,但我很困惑。如果我在我的application_controller中包含一個在/ lib中創建的模塊,我可以在我的功能測試中使用這些方法,如果是的話,那麼語法如何。 在測試之外,我可以簡單地通過鍵入some_method來使用這些方法,而無需使用模塊名稱的前綴,即Module :: some_method。 在測試雖然我沒有運氣。 – robodisco 2009-12-02 15:07:24

相關問題