2012-03-27 8 views
8

tengo una clase ActionMailerActionMailer método llamado de regresar a cero en el módulo mientras que las pruebas 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 

Si llamo UserMailer.submission_reminder(current_user) en el desarrollo me devuelve un objeto Mail::Message como se esperaba.

El lugar en mi aplicación en la que se llama a este método está en un módulo que tengo en la carpeta lib:

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

Cuando llamo TimesheetSubmissionNotifier.send_submission_reminders en el desarrollo, UserMailer.submission_remind (usuario) devuelve el mensaje de correo y se llama entrega, todo funciona como debería.

El problema es cuando llamo a TimesheetSubmissionNotifier.send_submission_reminders a través de una prueba rspec, UserMailer.submission_reminder(user) devuelve nil.

Si llamo a UserMailer.submission_reminder(user) directamente desde una prueba de rspec, devuelve el mensaje de correo como se esperaba.

Estas son las únicas líneas relacionadas con ActionMailer en mi config/medio/test.rb:

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

Cualquier idea por qué el método se vuelve nula?

+0

Cuando dices que llamar 'UserMailer.submission_reminder (user)' directamente desde una prueba rspec funciona, ¿cómo estás inicializando el objeto ** usuario ** que pasas al método? ¿Lo obtiene de la tabla Usuarios o lo construye con una fábrica, etc.? – Zheileman

Respuesta

16

Para aquellos que tienen un problema similar, encontré el problema.

Estaba usando la expectativa RSpec should_receive, que no me di cuenta de que realmente creó un simulacro de la clase en la que se coloca. Así que me burlaba de la clase UserMailer por completo, lo que significaba que nunca llegaba a la clase real de UserMailer.

No pude hacerlo funcionar usando las funciones simuladas, así que en su lugar cambié mi prueba para mirar la tienda UserMailer.deliveries y verifico que la cantidad correcta de mensajes se colocan allí y que se envían a la derecha correos electrónicos.

+1

Sí, hice esto también, hay un ejemplo fácil de google que hace esto. Vale la pena advertir a las personas que esta es una forma muy * incorrecta * de probar esto. Should_receive se burla de un punto final de método, pero no define ningún tipo de valor de retorno a menos que lo haga de forma explícita (la recepción no tiene nada que ver con la recepción de correos electrónicos ;-)). –

+1

Técnicamente, should_receive no crea un objeto simulado, resuelve el método y devuelve nil (los documentos rspec se refieren a esto como un simulacro parcial). Puede llamar al método original con and_call_original. p.ej. should_receive (: submission_reminder) .and_call_original –

+3

Nos encontramos con esta actualización a rails 4. Estábamos utilizando el retraso de sidekiq que cambió durante la actualización para generar un RuntimeError 'devolvió un objeto de correo no entregado' si el envío de correo devuelve nada. Mailer.should_receive (: submission_reminder) .and_call_original corrigió las pruebas. –

Cuestiones relacionadas