2012-03-27 14 views
8

Mam klasy ActionMailerActionMailer wywołanie metody powrocie nil w module podczas rspec testowanie

class UserMailer < ActionMailer::Base 
    default from: "[email protected]" 

    def submission_reminder user 
    @user = user   
    mail :to => user.email, :subject => "Your timesheet needs to be submitted!" 
    end  
end 

Jeśli zadzwonię UserMailer.submission_reminder(current_user) w rozwoju zwraca mi Mail::Message obiekt jak oczekiwano.

miejsce w mojej aplikacji, gdzie ta metoda jest wywoływana jest w module mam w folderze lib:

module TimesheetSubmissionNotifier        
    def self.send_submission_reminders 
    User.all.each { |user| UserMailer.submission_reminder(user).deliver } 
    end 
end 

Kiedy zadzwonić TimesheetSubmissionNotifier.send_submission_reminders w rozwoju, UserMailer.submission_remind (użytkownik) zwraca wiadomości i dostarczanie jest nazywane, wszystko działa tak, jak powinno.

Problem polega na tym, że wywołuję TimesheetSubmissionNotifier.send_submission_reminders poprzez test rspec, UserMailer.submission_reminder(user) zwraca zero.

Jeśli zadzwonię pod numer UserMailer.submission_reminder(user) bezpośrednio z testu rspec, to zwróci wiadomość mailer tak, jak powinna.

Oto tylko linie związane z ActionMailer w moim config/środowiska/test.rb:

config.action_mailer.delivery_method = :test 
config.action_mailer.default_url_options = { :host => 'localhost:3000' } 

jakieś pomysły dlaczego metoda zwraca nil?

+0

Kiedy mówisz, że wywołanie 'UserMailer.submission_reminder (user)' bezpośrednio z testu rspec działa, jak inicjujesz ** obiekt ** użytkownika, który przekazałeś do metody? Dostajesz go ze stołu użytkowników lub budujesz go w fabryce itp.? – Zheileman

Odpowiedz

16

Dla tych, którzy mają podobny problem, znalazłem problem.

Wykorzystałem oczekiwanie RSpec na should_receive, którego nie zdawałem sobie sprawy, faktycznie stworzyłem próbę klasy, w której się znajduje. Więc kpiłem z klasy UserMailer całkowicie, co oznaczało, że nigdy nie dotarł do rzeczywistej klasy UserMailer.

Nie udało mi się uruchomić go przy użyciu fałszywych funkcji, więc zamiast tego zmieniłem test, aby przejrzeć sklep UserMailer.deliveries i sprawdzić, czy włożono tam odpowiednią ilość wiadomości i czy są one przesyłane w prawo. adresy e-mail.

+1

Tak, zrobiłem to również, jest łatwy do Google przykład, który to robi. Warto ostrzegać ludzi, że jest to bardzo zły sposób na sprawdzenie tego. Should_receive kpi z punktu końcowego metody, ale nie definiuje żadnej wartości zwracanej, chyba że robisz to wyraźnie (odbiór nie ma nic wspólnego z otrzymywaniem wiadomości e-mail ;-)). –

+1

Z technicznego punktu widzenia funkcja should_receive nie tworzy obiektu symulowanego, metoda ta jest niedostępna i zwraca zero (dokumenty rspec określają to jako częściową próbę). Możesz wywołać oryginalną metodę z __call_original. na przykład. should_receive (: submission_reminder) .and_call_original –

+3

Natrafiliśmy na tę aktualizację do szyn 4. Używaliśmy opóźnienia sidekiq, które zmieniło się podczas aktualizacji, aby podnieść RuntimeError "zwrócił niedostarczalny obiekt poczty", jeśli mailer zwróci zero. Mailer.should_receive (: submission_reminder) .and_call_original naprawił testy. –

Powiązane problemy