10

現在、コントローラーの仕様には次のものがあります。

require 'spec_helper'

describe CustomerTicketsController do
  login_user

  describe "POST /create (#create)" do
    # include EmailSpec::Helpers
    # include EmailSpec::Matchers
    it "should deliver the sales alert email" do
      # expect
      customer_ticket_attributes = FactoryGirl.attributes_for(:customer_ticket)
      customer_mailer = mock(CustomerMailer)
      customer_mailer.should_receive(:deliver).
        with(CustomerTicket.new(customer_ticket_attributes))
      # when
      post :create, :customer_ticket => customer_ticket_attributes
    end
  end
end

私のコントローラーには次のものがあります:

  # POST /customer_tickets
  # POST /customer_tickets.xml
  def create
    respond_to do |format|
      if @customer_ticket.save
        CustomerMailer.sales_alert(@customer_ticket).deliver
        format.html { redirect_to @customer_ticket, notice: 'Customer ticket was successfully created.' }
        format.xml { render xml: @customer_ticket, status: :created, location: @customer_ticket }
      else
        format.html { render action: "new" }
        format.xml { render xml: @customer_ticket.errors, status: :unprocessable_entity }
      end
    end
  end

私のテストは現在、次の出力を生成します。

Failures:

  1) CustomerTicketsController POST /create (#create) should deliver the sales alert email
     Failure/Error: customer_mailer.should_receive(:deliver).
       (Mock CustomerMailer).deliver(#<CustomerTicket id: nil, first_name: "firstname1", last_name: "lastname1", company: nil, referral: nil, email: "firstname1@example.com", phone: "555-5555", fax: nil, country: nil, address1: "555 Rodeo Dr.", address2: nil, city: "Beverly Hills", state: "CA", postcode: "90210", question: "The answer to the universe is 4.", type: nil, status: nil, priority: nil, number: nil, cs_rep_id: nil, created_at: nil, updated_at: nil>)
           expected: 1 time
           received: 0 times
     # ./spec/controllers/customer_ticket_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

Finished in 0.52133 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/customer_ticket_controller_spec.rb:9 # CustomerTicketsController POST /create (#create) should deliver the sales alert email

ご覧いただきありがとうございます。

4

3 に答える 3

18

ActionMailer::Base.deliveries.count をチェックして、1 ずつ増加していることを確認できます。

このようなもの(未テスト)

expect {custom_mailer.deliver}.to change { ActionMailer::Base.deliveries.count }.by(1)
于 2012-06-04T17:44:21.620 に答える
1

設定しているモックは、実際に実行されているものと一致しません。deliver作成しているモックを実際に呼び出す必要があります。

何かのようなもの

message = mock('Message')
CustomerMailer.should_receive(:sales_alert).and_return(message)
message.should_receive(:deliver)

通過する必要があります。

渡されたものを確認したい場合、何をしているのsales_alertかはうまくいきません - アクティブなレコードは主キーの同等性によってのみオブジェクトを比較するため、仕様で作成している顧客チケットは仕様で作成したものと等しくなりませんあなたのコントローラー。

あなたができることの1つは

CustomerMailer.should_receive(:sales_alert) do |arg|
  ...
end.and_return(message)

rspecsales_alertは呼び出されたものをすべて生成し、必要なチェックを行うことができます

それを行う別の方法は、スタブアウトCustomerTicket.newすることです。これにより、返されるものを制御できます。たとえば、

mock_ticket = mock(CustomerTicket)
CustomerTicket.should_receive(:new).with(customer_ticket_attributes).and_return(mock_ticket)
mock_ticket.should_receive(:save).and_return(true)
CustomerMailer.should_receive(:sales_alert).with(mock_ticket).and_return(message)

最後に、このアラートの送信は実際には のインスタンス メソッドに属すべきであると判断するかもしれません。このCustomerTicket場合、コントローラの仕様は、send_sales_alertメソッドがチケットで呼び出されたことを確認するだけで済みます。

于 2012-06-04T17:34:46.323 に答える