1

我在 lib 目录中创建了一个模块,我可以在我的 Rails 应用程序中自由调用它包含的各种方法(添加包含 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 < 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 => "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
4

2 回答 2

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
于 2009-12-01T14:04:59.687 回答
1

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

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

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

SpreedlyTools.spreedly_signup_url user

现在这是有道理的。

模块用于将代码混合到其他类中。但是,如果您只想随时使用通用工具,那么您确实需要类级别的功能。

于 2009-12-01T17:03:00.890 回答