Rspec测试:NotificationMailer.user_notification(self)返回nil

时间:2015-09-18 04:47:22

标签: ruby-on-rails rspec

我的某个测试遇到了问题

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)会返回正确的对象。这意味着我的测试不起作用......

你会解决什么?

1 个答案:

答案 0 :(得分:2)

使用expect.to receive mock - 基本上是一个期望的存根(纯粹主义者可能不同意,但无论如何)。你已经剔除了你所期望的方法,因此它不会被调用。通常,您还会指定返回值,因此您正在测试的其余代码将继续使用该返回值。

您未在此处指定返回值,因此模拟返回nil,使得其余代码(取决于实际返回值)爆炸。

这里有两种典型的行动方式:

  • 在模拟结束时使用.and_call_original - 这基本上意味着模拟不会像存根一样,并且会使用您传入的参数调用原始方法。在这种情况下,可能不希望这样,因为它是邮件程序,并且您不想在您的规范中发送电子邮件。

  • 使用.and_return指定存根的返回值。在这种情况下,您可能需要以下内容:

    expect(NotificationMailer)。接收(:user_notification).with(an_instance_of(User))。and_return(double(deliver:true))

当您致电NotificationMailer.user_notification时,这会向您的代码返回测试双,它会响应deliver方法并返回true

有关测试双打的更多信息,请参阅RSpec Mocks文档:

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