Rails – 为什么我不能在我的测试中使用我在模块中创建的方法?

我在lib目录中创建了一个模块,我可以在我的Rails应用程序(添加include ModuleName之后)中自由调用它包含的各种方法,没有任何问题。

然而,当谈到测试时,他们抱怨没有这样的方法。 我尝试将模块包含在我的测试助手中,但没有运气。 谁能帮忙。

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  {:first_name => "bobby", :last_name => "brown", :email => "bobby.brown@gmail.com", :email_confirmation => "bobby.brown@gmail.com", :password => "bobby1", :password_confirmation => "bobby1"} assert_response :redirect user = assigns(:user) assert_redirected_to SpreedlyTools.spreedly_signup_url(user) end end 

这里有几个不同的错误。 首先,当您创建模块并将模块的内容混合到一个类中时,模块中的方法将成为类本身的一部分。

也就是说,以下行没有意义

 assert_redirected_to SpreedlyTools.spreedly_signup_url(user) 

假设您将模块混合到User类中,则应将该方法调用为

 assert_redirected_to User.new.spreedly_signup_url(user) 

另请注意new声明。 因为您将模块包含在类中而不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 

啊,这是一个微妙的问题,但很容易纠正。 您不想在测试套件中包含SpreedlyTools,而是要测试由包含SpreedlyTools的类创建的对象。

在Ruby中,您可能会发现Classes的工作方式与您认为模块的工作方式相当。 您可以通过定义类级别函数来使用它:

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

这现在有意义了。

模块用于将代码混合到其他类中。 但是,如果您只是想要随时可用的通用工具,那么您真的需要类级function。