【问题标题】:Check if line got executed with Rspec检查是否使用 Rspec 执行了行
【发布时间】:2021-03-03 09:22:39
【问题描述】:
我有一个工作人员在新的反馈出现时向用户发送电子邮件。我想让用户不同意这一点(带有西施标志)。问题是:如果FedbackMailer.new_feedback 行被执行,我如何测试(使用Rspec)?
account.users.each do |user|
return if (user.no_notifications || user.just_summary)
FeedbackMailer.new_feedback(account.id, feedback_id, user.id).deliver_later
end
【问题讨论】:
标签:
ruby-on-rails
email
testing
rspec
【解决方案1】:
您可以使用rspec-mocks。
mailer = instance_double
allow(FeedbackMailer).to receive(:new_feedback).with(account_id, feedback_id, user_id).and_return(mailer)
allow(mailer).to receive(:deliver_later)
## do stuff ##
expect(mailer).to have_received(:deliver_later)
如果您当时没有要传递的参数,也可以忽略 .with。
另一种解决方案是设置配置config.action_mailer.delivery_method = :test 并检查交付计数是否已更改。
expect {
## code that deliver the email
}.to change { ActionMailer::Base.deliveries.count }.by(1)
【解决方案2】:
假设您的逻辑封装在MyClass类中的以下方法中
class MyClass
def my_method
account.users.each do |user|
return if (user.no_notifications || user.just_summary)
FeedbackMailer.new_feedback(account.id, feedback_id, user.id).deliver_later
end
end
end
RSpec.describe MyClass, type: :model do
context "#my_method" do
it "should send new feedback" do
user_obj = create_user
expect(user_obj.no_notifications).to be_falsey
#OR
#expect(user_obj.just_summary).to be_falsey
account_obj = create_account
account_obj.users << user_obj
expect(account_obj.users).to include(user_obj)
expect(FeedbackMailer).to receive(:new).with(account_obj.id, feedback_id, user_obj.id)
# OR in case you don't have feedback_id then you can use
# expect(FeedbackMailer).to receive(:new).with(account_obj.id, kind_of(Numeric), user_obj.id)
# You should also setup expectation here that `FeedbackMailer` gets enqueued to ensure
# that your method also gets invoked and the job also gets enqueued.
subject.my_method
end
end
end
希望对您有所帮助。谢谢。