[rspec] Problem z stub method z wieloma argumentami

Witam, testuje observer czy po danej akcji wywołane zostanie wysłanie 2 maili,

[code=ruby]describe DateInvitationObserver do

before do

@date_invitation = create :date_invitation, invitee: @invitee, inviter: @inviter, event: @event
@date_invitation_mailer = mock(DateInvitationMailer)
end

it ‘should send emails to matched persons’ do
ActiveRecord::Observer.with_observers(:date_invitation_observer) do
DateInvitationMailer.stub(:date_matched_email).with(@invitee, @inviter, @event).and_return(@date_invitation_mailer)
@date_invitation_mailer.should_receive(:deliver).exactly(2).times
@date_invitation.accept!
end
end[/code]
Jednak dostaje błąd:

[quote]<DateInvitationMailer (class)> received :date_matched_email with unexpected arguments
Please stub a default value first if message might be received with other args as well.[/quote]
Jeśli zmienie linię na

DateInvitationMailer.stub(:date_matched_email).with(any_args()).and_return(@date_invitation_mailer)

test przechodzi

Aha, wcześniej miałem metode date_matched_email z tylko jednym argumentem, wtedy test także przechodził

DateInvitationMailer.stub :date_matched_email => @date_invitation_mailer

Jeżeli oczekujesz, że dana metoda powinna zostać wywołana z określonymi parametrami to użyj should_receive

btw. to tylko kwestia gustu ale czemu nie używasz let() ?

[code]describe DateInvitationObserver do
let(:date_invitation) { create :date_invitation, invitee: @invitee, inviter: @inviter, event: @event }
let(:date_invitation_mailer) { mock :date_invitation_mailer }
before do
DateInvitationMailer.stub :date_matched_email => date_invitation_mailer
end

it ‘should send emails to matched persons’ do
ActiveRecord::Observer.with_observers(:date_invitation_observer) do
date_invitation_mailer.should_receive(:deliver).exactly(2).times
date_invitation.accept!
end
end[/code]

zmieniłem na coś takiego, testy zielone ale nie bardzo rozumiem czemu to działa a wcześniej nie chciało:

it 'should send emails to matched persons' do DateInvitationMailer.stub date_matched_email: @date_invitation_mailer DateInvitationMailer.stub(:date_matched_email).with(@invitee, @inviter, @event).and_return(@date_invitation_mailer) @date_invitation_mailer.should_receive(:deliver).exactly(2).times @date_invitation.accept! end

a zamiast tego

DateInvitationMailer.stub date_matched_email: @date_invitation_mailer DateInvitationMailer.stub(:date_matched_email).with(@invitee, @inviter, @event).and_return(@date_invitation_mailer)
nie powinno być

DateInvitationMailer.should_receive(:date_matched_email).with(@invitee, @inviter, @event).and_return @date_invitation_mailer

#stub wymusza to co obiekt ma zwrócić a #should_receive sprawdza czy metoda została wywołana, z jakimi parametrami i ewentualnie można powiedzieć co ma zwrócić

Zlw: Zależy co jest obiektem testu. Kod wskazuje, że testowane jest czy są wysyłane dwa (bliżej niesprecyzowane) mejle:

@date_invitation_mailer.should_receive(:deliver).exactly(2).times

Pytanie czy to autor miał na myśli.

obie strony otrzymują maila z tej samej metody, tylko inne dane sa podstawiane, na podstawie Waszych porad skleciłem coś takiego

it 'should send emails to matched persons' do date_invitation_mailer = mock(DateInvitationMailer) DateInvitationMailer.should_receive(:date_matched_email).with(@inviter, @invitee, @event).and_return date_invitation_mailer DateInvitationMailer.should_receive(:date_matched_email).with(@invitee, @inviter, @event).and_return date_invitation_mailer date_invitation_mailer.should_receive(:deliver).exactly(2).times @date_invitation.accept! end

(mój błąd)

tam są inne dane przekazywane do metody :with