簡體   English   中英

如何使用rspec測試我的郵件程序中是否設置了實例變量?

[英]how do I test that an instance variable is set in my my mailer with rspec?

如何使用rspec測試我的郵件程序中是否設置了某個實例變量? 分配回來未定義..

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>

assigns僅針對控制器規范定義,並且通過rspec-rails gem完成。 在RSpec中沒有測試實例變量的通用機制,但您可以使用Kernel的instance_variable_get來訪問您想要的任何實例變量。

所以在你的情況下,如果object是你想要檢查的實例變量的對象,你可以寫:

expect(object.instance_variable_get(:@person)).to eql(user)

至於獲取UserMailer實例,我看不到任何方法。 查看https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb中的method_missing定義,只要調用具有相同名稱的未定義類方法,就會創建一個新的郵件程序實例作為實例方法。 但是這個實例並沒有保存在我能看到的任何地方,只返回了.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

除非Rails更改其實現,以便它實際上提供對ActionMailer(控制器)對象的訪問而不僅僅是生成的Mail對象,我認為這不可能進行測試。

正如Peter Alfvin指出的那樣,問題在於它返回了“消息”:

new(method_name, *args).message

而不是像這樣返回郵件程序(控制器):

new(method_name, *args)

rspec-rails列表中的這篇文章也可能有所幫助:

似乎合理,但不太可能改變。 這就是原因。 rspec-rails提供了rails提供的測試類的包裝器。 Rails功能測試支持您上面提出的三個問題,但是rails mailer測試是不同的。 來自http://guides.rubyonrails.org/action_mailer_basics.html :“測試郵件通常涉及兩件事:一件是郵件排隊,另一件是郵件正確。”

為了支持您希望在郵件程序規范中看到的內容,rspec-rails必須提供它自己的ExampleGroup(而不是包裝rails類),這必須與rails的內部緊密綁定。 我在rspec-rails-2中花了很大力氣來限制與公共API的耦合,這有一個很大的回報:我們只有一個案例,其中rails 3.x版本需要發布rspec-rails(即有一個突破性的變化)。 使用rails-2,幾乎每個版本都破壞了rspec-rails,因為rspec-rails與內部結構相關(rspec-rails的錯誤,而不是rails)。

如果你真的想看到這個變化,你需要在rails本身中更改它,此時rspec-rails將很樂意包裝新的和改進的MailerTestCase。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM