2012-03-27 10 views
8

Ho una classe ActionMailermetodo ActionMailer chiamata di ritorno pari a zero nel modulo durante il test rspec

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 

Se chiamo UserMailer.submission_reminder(current_user) in fase di sviluppo mi restituisce un oggetto Mail::Message come previsto.

Il posto nella mia applicazione in cui viene chiamato questo metodo è in un modulo che ho nella cartella lib:

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

Quando chiamo TimesheetSubmissionNotifier.send_submission_reminders in fase di sviluppo, UserMailer.submission_remind (utente) restituisce il messaggio di posta e consegnare è chiamato, tutto funziona come dovrebbe.

Il problema è quando chiamo TimesheetSubmissionNotifier.send_submission_reminders attraverso un test rspec, UserMailer.submission_reminder(user) restituisce zero.

Se chiamo UserMailer.submission_reminder(user) direttamente da un test rspec, restituisce il messaggio di posta elettronica come previsto.

Qui ci sono le uniche linee relative alla ActionMailer nel mio config/ambiente/test.rb:

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

Tutte le idee perché il metodo sta tornando a zero?

+0

Quando dici di chiamare 'UserMailer.submission_reminder (utente)' direttamente da un test rspec, come stai inizializzando l'oggetto ** utente ** che passi al metodo? Lo ottieni dalla tabella Utenti o lo costruisci con una fabbrica, ecc.? – Zheileman

risposta

16

Per coloro che hanno un problema simile, ho trovato il problema.

Stavo usando l'aspettativa RSpec should_receive, che non avevo realizzato in realtà creato una simulazione della classe su cui è posizionata. Quindi stavo prendendo in giro la classe UserMailer, il che significava che non avrebbe mai raggiunto la classe UserMailer effettiva.

Non riuscivo a farlo funzionare utilizzando le funzioni di simulazione, quindi ho modificato il mio test per guardare lo store UserMailer.deliveries e controllare che la giusta quantità di messaggi sia inserita e che sia stata inviata a destra indirizzi email.

+1

Sì, l'ho fatto anche io, c'è un semplice esempio di google che fa questo. Vale la pena avvertire che questo è un modo * errato * per testare questo. Should_receive sta prendendo in giro un endpoint del metodo, ma non definisce alcun tipo di valore di ritorno a meno che non lo faccia esplicitamente (la ricezione non ha nulla a che fare con la ricezione di e-mail ;-)). –

+1

Tecnicamente, should_receive non crea un oggetto fittizio, stuba il metodo e restituisce nil (i documenti rspec si riferiscono a questo come un mock parziale). Puoi chiamare il metodo originale con and_call_original. per esempio. should_receive (: submission_reminder) .and_call_original –

+3

Ci siamo imbattuti in questo aggiornamento ai binari 4. Stavamo usando il ritardo sidekiq che è cambiato durante l'aggiornamento per generare un RuntimeError 'restituito un oggetto di posta non consegnabile' se il mailer restituisce nil. Mailer.should_receive (: submission_reminder). And_call_original ha corretto i test. –

Problemi correlati