2015-09-18 18 views
2

我遇到了我的測試一個Rspec的測試:NotificationMailer.user_notification(個體經營)返回nil

Rspec的

it 'should call send_email_notification on NotificationMailer' do 
    expect(NotificationMailer).to receive(:user_notification).with(an_instance_of(User)) 
    FactoryGirl.create(:user, shop: Shop.new) 
    end 

方法麻煩:

def send_email_notification 
    if user? && self.shop.email_notifications 
     NotificationMailer.user_notification(self).deliver_now 
    end 
    end 

未定義的方法` deliver_now'爲零:NilClass

這意味着NotificationMailer.user_notification(self)在測試期間返回nil。但是,當我在真正的本地環境中運行binding.pry時,NotificationMailer.user_notification(self)會返回適當的對象。這意味着我的測試不起作用...

你會解決什麼問題?

回答

2

使用expect.to receive模擬 - 基本上是一個存在期望的存根(純粹主義者可能會不同意,但無論如何)。你正在剔除你所期望的方法,所以它不會被調用。通常,您還要指定返回值,因此您正在測試的其餘代碼將繼續使用該返回值。

你沒有在這裏指定返回值,所以模擬返回nil,讓你的代碼的其餘部分(這取決於真正的返回值)炸燬。

有作用的兩種典型的課程在這裏:

  • 在結束使用.and_call_original你的模擬 - 這基本上意味着,模擬不會像存根,它會調用原始的方法與您通過的參數進行比較。在這種情況下,您可能不希望出現這種情況,因爲它是郵件程序,並且您不希望在規範中發送電子郵件。

  • 指定存根的返回值,.and_return。在這種情況下,你可能想是這樣的:

    預期(NotificationMailer)。爲了接收(:user_notification)。隨着(an_instance_of(用戶))and_return(雙(提供:真))。

當您致電NotificationMailer.user_notification時,這將返回一個測試雙重到您的代碼,這將響應deliver方法並將返回true

上測試雙打的更多信息可以在RSpec的嘲弄文檔中找到:

https://relishapp.com/rspec/rspec-mocks/docs

+0

人,這是我收到過的最好的答案之一。謝謝 –