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 < 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
Ответы
Ответ 1
Здесь есть несколько разных ошибок.
Во-первых, когда вы создаете модуль и смешиваете содержимое модуля с классом, методы внутри модуля становятся частью самого класса.
Тем не менее, следующая строка не имеет смысла
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
Ответ 2
А, это тонкая проблема, но она легко исправлена. Вместо того чтобы включать SpreedlyTools в ваш тестовый пакет, вы хотите протестировать объекты, созданные классами, которые включают SpreedlyTools.
В Ruby вы можете обнаружить, что Классы работают намного больше, как вы думаете, что модули работают. Вы можете использовать функцию уровня класса, определяя ее как таковую:
class SpreedlyTools
def self.spreedly_signup_url user
...
end
end
SpreedlyTools.spreedly_signup_url user
Теперь это будет иметь смысл.
Модули предназначены для смешивания кода с другими классами. Но если вы просто хотите, чтобы универсальные инструменты были доступны в любое время, вам действительно нужны функции уровня класса.