Как проверить, что переменная экземпляра установлена в моей моей почтовой программе с помощью rspec?
Как проверить, что определенная переменная экземпляра установлена в моей моей почтовой программе с помощью rspec? присваивает возвращается undefined..
require File.dirname(__FILE__) + '/../../spec_helper'
describe UserMailer do
it "should send the member user password to a User" do
user = FG.create :user
user.create_reset_code
mail = UserMailer.reset_notification(user).deliver
ActionMailer::Base.deliveries.size.should == 1
user.login.should be_present
assigns[:person].should == user
assigns(:person).should == user #both assigns types fail
end
end
Возвращенная ошибка:
undefined local variable or method `assigns' for #<RSpec::Core::ExampleGroup::Nested_1:0x007fe2b88e2928>
Ответы
Ответ 1
assigns
определяется только для спецификаций контроллера и выполняется с помощью rspec-rails gem. В RSpec нет общего механизма проверки переменных экземпляра, но вы можете использовать Kernel instance_variable_get
для доступа к любой переменной экземпляра, которую вы хотите.
Итак, в вашем случае, если object
был объектом, переменная экземпляра которого вы интересовали, вы можете написать:
expect(object.instance_variable_get(:@person)).to eql(user)
Что касается получения экземпляра UserMailer
, я не вижу никакого способа сделать это. Глядя на определение method_missing
внутри https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb, новый экземпляр почтовой программы будет создан всякий раз, когда вызывается метод класса undefined с тем же именем, что и метод экземпляра, Но этот экземпляр не сохраняется нигде, что я вижу, и возвращается только значение .message
. Вот соответствующий код, определенный в настоящее время в github:
Методы класса:
def respond_to?(method, include_private = false) #:nodoc:
super || action_methods.include?(method.to_s)
end
def method_missing(method_name, *args) # :nodoc:
if respond_to?(method_name)
new(method_name, *args).message
else
super
end
end
Методы экземпляра:
attr_internal :message
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
# will be initialized according to the named method. If not, the mailer will
# remain uninitialized (useful when you only need to invoke the "receive"
# method, for instance).
def initialize(method_name=nil, *args)
super()
@_mail_was_called = false
@_message = Mail.new
process(method_name, *args) if method_name
end
def process(method_name, *args) #:nodoc:
payload = {
mailer: self.class.name,
action: method_name
}
ActiveSupport::Notifications.instrument("process.action_mailer", payload) do
lookup_context.skip_default_locale!
super
@_message = NullMail.new unless @_mail_was_called
end
end
Ответ 2
Я не думаю, что это возможно проверить, если Rails не изменит свою реализацию, так что он фактически обеспечивает доступ к объекту ActionMailer (controller), а не только к создаваемому объекту Mail.
Как отметил Питер Альфвин, проблема в том, что он возвращает "сообщение" здесь:
new(method_name, *args).message
вместо того, чтобы просто возвращать почтовую программу (контроллер) следующим образом:
new(method_name, *args)
Этот post в списке rspec-rails также может быть полезен:
Кажется разумным, но вряд ли изменится. Вот почему. RSpec рельсы обеспечивает обертки вокруг тестовых классов, предоставляемых рельсами. Рельсы функциональные тесты поддерживают три вопроса, которые вы ставите выше, но рельсы тесты почтовой программы отличаются. Из http://guides.rubyonrails.org/action_mailer_basics.html: "Тестирование почтовые программы обычно связаны с двумя вещами: во-первых, почта была поставлена в очередь, а другой - правильно."
Чтобы поддерживать то, что вы хотели бы видеть в спецификациях почтовой программы, rspec-rails должны предоставить ему собственную ExampleGroup (а не обернуть рельсы класс), который должен быть тесно связан с внутренними элементами рельсов. я приложили большие усилия в rspec-rails-2, чтобы ограничить связь с общественностью API, и у этого был большой выигрыш: у нас был только один случай, когда rails 3.x требуется выпуск rspec-рельсов (т.е. был нарушение изменение). С рельсами-2 почти в каждом выпуске rspec-rails, потому что rspec-рельсы были привязаны к внутренним (rspec-rails ' неисправность, а не рельсы).
Если вы действительно хотите увидеть это изменение, вам нужно его изменить в рельсах, и в этот момент rspec-rails с радостью и улучшенный MailerTestCase.