【问题标题】:Stubbing ActionMailer in Rspec在 Rspec 中存根 ActionMailer
【发布时间】:2014-09-15 04:14:40
【问题描述】:

问候!
我正在尝试使用如下所示的 Rspec 测试控制器方法:

def email_customer
  @quote = Quote.find(params[:quote_id])
  hash = {
    quote: @quote,
    body: params[:email_body],
    subject: params[:email_subject]
  }
  QuoteMailer.email_customer(hash).deliver
  redirect_to edit_quote_path params[:quote_id]
end

相应的规范如下所示:

describe 'POST email_customer' do
  let!(:quote) { create(:valid_quote) }
  it 'assigns the quote and sends the customer an email' do
    post :email_customer, quote_id: quote.id
    expect(assigns(:quote)).to eq(quote)
    expect(QuoteMailer).to receive(:email_customer).with(an_instance_of(Hash)).and_return( double('QuoteMailer', deliver: true))
  end
end

当测试运行时,我收到以下消息:

Failure/Error: expect(QuoteMailer).to receive(:email_customer).with(an_instance_of(Hash)).and_return( double('QuoteMailer', deliver: true))
       (<QuoteMailer (class)>).email_customer(an instance of Hash)
           expected: 1 time with arguments: (#<RSpec::Matchers::AliasedMatcher:0x0000000c2b1e28 @description_block=#<Proc:0x00000009816268@/home/david/.rvm/gems/ruby-2.1.1/gems/rspec-expectations-3.0.0.beta2/lib/rspec/matchers.rb:231 (lambda)>, @base_matcher=#<RSpec::Matchers::BuiltIn::BeAnInstanceOf:0x0000000c2b1e50 @expected=Hash>>)
           received: 0 times with arguments: (#<RSpec::Matchers::AliasedMatcher:0x0000000c2b1e28 @description_block=#<Proc:0x00000009816268@/home/david/.rvm/gems/ruby-2.1.1/gems/rspec-expectations-3.0.0.beta2/lib/rspec/matchers.rb:231 (lambda)>, @base_matcher=#<RSpec::Matchers::BuiltIn::BeAnInstanceOf:0x0000000c2b1e50 @expected=Hash>>)
     # ./spec/controllers/quotes_controller_spec.rb:28:in `block (3 levels) in <top (required)>'

我在控制器方法和 email_customer 方法中分散了 puts 语句,所以我知道它最终会运行它的过程并使用正确的方法,但我不确定它为什么会失败。我猜这是一个我不确定的愚蠢的语法错误。提前感谢您的帮助!

【问题讨论】:

  • 写你的expects 之前 post
  • 啊,我之前曾尝试将两个期望都放在帖子之前,这给了我关于@quote 分配的错误,但是在帖子之前的存根它完美地工作!谢谢你,先生!如果你回答我会接受它

标签: ruby-on-rails ruby rspec actionmailer


【解决方案1】:

消息expectations 应该出现在您要测试的方法的调用之前,因为它们实际上是在对象中存根消息:

describe 'POST email_customer' do
  let!(:quote) { create(:valid_quote) }
  it 'assigns the quote and sends the customer an email' do
    expect(QuoteMailer).to receive(:email_customer).with(an_instance_of(Hash)).and_return( double('QuoteMailer', deliver: true))

    post :email_customer, quote_id: quote.id

    expect(assigns(:quote)).to eq(quote)
  end
end

【讨论】:

  • 在帖子之前有expect(assigns(:quote)).to eq(quote) 导致我出现此错误:Failure/Error: expect(assigns(:quote)).to eq(quote): expected: #&lt;Quote id: 1, email: "test@example.com", phone_number: nil, first_name: "test", last_name: "mctesterson", company: nil, twitter: nil, name: nil, valid_until_date: "2014-07-24 20:00:37", estimated_delivery_date: "2014-07-24 20:00:37", salesperson_id: 2, store_id: 3, deleted_at: nil, created_at: "2014-07-23 20:00:38", updated_at: "2014-07-23 20:00:38"&gt; got: nil
  • @davidicus - 难道它根本没有通过? (它收到的值为nil
  • 不,因为当我将 expect(assigns(:quote)).to eq(quote) 移动到 之后 post :email_customer, quote_id: quote.id 它通过了
  • @davidicus - 对不起,我误导了你。 expect(assigns... 应该在通话之后,因为它不是消息期望...只有消息期望应该在通话之前...我已经更新了我的答案
  • @UriAgassi - 我的 action mailer 期待 params 哈希 - 你知道如何在 rspec mailer 测试中直接存根它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 2011-08-16
  • 2012-12-25
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多