Estoy seguro de que esto se responde en alguna parte; Sin embargo, parece que no puedo formular correctamente mi búsqueda en Google. Estoy tratando de probar que se llama a un método en un objeto, pero el método no se llama en el objeto específico en la especificación. Se llama al método en el último elemento de una colección, que he confirmado que es el mismo objeto subyacente que el de la especificación. No estoy seguro de cuán claro fue eso, así que aquí hay un ejemplo:
expect(@email).to receive(:send) # fails puts @user.emails.last == @email # true @user.emails.last.send Como control de cordura, esta especificación pasa. Sin embargo, el código que estoy probando tiene @user.emails.last.send , así que estoy tratando de descubrir cómo hacer que la especificación anterior pase.
expect(@email).to receive(:send) # passes @email.sendEditar:
@user.emails.last.equal?(@email) devuelve falso, por lo que @spickermann y @Grzegorz sospechan que @user.emails.last y @email son dos instancias del mismo objeto. Entonces, supongo que lo que estoy preguntando es cómo puedo probar que el método de send se invocó en un objeto específico (ignorando a qué instancia particular de ese objeto se invocó). Mi pregunta es en realidad la misma que acabo de encontrar Rspec: Probar si se llamó al método de instancia en un registro específico con ActiveRecord .
Es posible que el método == esté definido en el objeto de correo de manera que devuelva verdadero si algunos atributos son iguales, pero no importa si el objeto es el mismo.
@user.emails.last == @emailEste es el caso con una cadena simple:
>> "d" == "d" => true >> "d".object_id == "d".object_id => false Entonces, es posible que @mail y @user.emails.last sean objetos diferentes en la memoria, pero devuelvan verdadero cuando se usa el método == .
Puede confirmar que no hay nada malo con su expectativa de esta manera:
expect(@user.emails.last).to receive(:send) # should pass now @user.emails.last.sendNo compartió mucho código para el contexto, por lo que no está claro cuál podría ser una solución "buena" en su caso. Pero espero que esto te oriente en la dirección correcta.
En mi caso, puedo solucionar esto devolviendo la instancia de correo electrónico ( @user.emails.last ) del método send_email y asegurándome de que sea el mismo objeto que el objeto @email en la especificación. P.ej,:
# The `send_email` method calls `@user.emails.last.send` and returns `@user.emails.last` email = @user.send_email expect(email).to eq(@email) # passes!