Reputation: 519
In mailer of rails, as I know all method will be class method. But I can not test my mailer method called:
user_mailer_spec.rb:
it "should call send_notifition method" do
@user = FactoryGirl.build(:user)
notify_email = double(:send_notifition)
expect(UsersMailer.new).to receive(:notify_email).with(@user)
@user.save
end
user_mailer.rb:
def notify(user)
mail to: user.email, subject: "Example"
end
user.rb:
after_commit :send_notifition
private
def send_notifition
UsersMailer.notify(self)
end
The above codes will not pass but when I change notifition to self.notifition, it pass:
def self.notify(user)
mail to: user.email, subject: "Example"
end
Upvotes: 0
Views: 1805
Reputation: 519
Solved: Thank you @Clemens Kofler for supporting. I have many mistaking in my code:
from
after_commit :send_notifition
private
def send_notifition
UsersMailer.notify(self)
end
to
after_commit :send_notifition
private
def send_notifition
UsersMailer.notify(self).deliver
end
from
it "should call send_notifition method" do
@user = FactoryGirl.build(:user)
expect(@user).to receive(:send_notifition)
notify_email = double(:send_notifition)
expect(UsersMailer.new).to receive(:notify_email).with(@user)
@user.save
end
to
it "should call send_notifition_mail_if_created_new_hospital method" do
@user = FactoryGirl.build(:user)
# I don't know why "expect(@user).to receive(:send_notifition)" not passed here
mail = double(:mail)
expect(UsersMailer).to receive(:notify_email).with(@user).and_return(mail)
allow(mail).to receive(:deliver)
@user.save
end
Upvotes: 1
Reputation: 1968
First of all, I'd like to point you to an awesome gem for testing emails: https://github.com/email-spec/email-spec.
I think the problem is that you're asserting on UsersMailer.new
, thus putting a mock on a different instance than the one then being instantiated by the User
model. I generally test emails like this without any issues:
it "should call send_notifition method" do
@user = FactoryGirl.build(:user)
mail = double(:mail)
expect(UsersMailer).to receive(:notify_email).with(@user).and_return(mail)
expect(mail).to receive(:deliver_later) # or deliver_now, if you don't use a background queue
@user.save
end
Note how I'm doing expect(UsersMailer)
instead of expect(UsersMailer.new)
and also take not that I'm asserting that the email is actually delivered (I think a deliver statement is missing in your code).
Hope that helps.
Upvotes: 4