10

は、現在私が持っている私のコントローラの仕様に:電子メールが送信されることを確認するRspecコントローラテストを作成するにはどうすればよいですか?

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 

私が持っている私のコントローラでは:

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: "[email protected]", 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 

感謝:

# 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 

私のテストは、現在、次の出力を生成しますあなたは探しています。

答えて

18

あなたはそれがこれはメーラーであることをテストする方法の方法である(未テスト)このような1

何か

expect {custom_mailer.deliver}.to change { ActionMailer::Base.deliveries.count }.by(1) 
+2

expectブロックの内部に 'post:create、:customer_ticket => customer_ticket_attributes'を置いて、それは仕事をしているようです。 – jklina

1

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

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

よう

何かが通過しなければなりません。

sales_alertに渡された内容を確認したい場合は、実行中のレコードは主キーの等価性によってオブジェクトを比較するだけで、スペックで作成する顧客チケットは等しくないあなたのコントローラで作成されたものに変更します。

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

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

RSpecのがと呼ばれ、あなたはそう、あなたがそれを行うための別の方法は、CustomerTicket.newをスタブアウトすることです

をしたいチェックものは何でもできるものは何でもsales_alert得られますです例えば、

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メソッドがチケットで呼び出されたことを確認できます。

0

ずつ増加していることを確認するためにactionmailerの:: Base.deliveries.countをチェックすることができます正しい引数で呼ばれます。

delivery = double 
expect(delivery).to receive(:deliver_now).with(no_args) 

expect(CustomerMailer).to receive(:sales_alert) 
    .with(customer_ticket) 
    .and_return(delivery) 
関連する問題