在 RSpec 测试后清除 ActionMailer::Base.deliveries
Posted
技术标签:
【中文标题】在 RSpec 测试后清除 ActionMailer::Base.deliveries【英文标题】:Clearing out ActionMailer::Base.deliveries after RSpec test 【发布时间】:2011-08-16 03:25:56 【问题描述】:我的 UserMailer 类有以下 RSpec 测试:
require "spec_helper"
describe UserMailer do
it "should send welcome emails" do
ActionMailer::Base.deliveries.should be_empty
user = Factory(:user)
UserMailer.welcome_email(user).deliver
ActionMailer::Base.deliveries.should_not be_empty
end
end
此测试第一次通过,但第二次运行失败。在进行了一些调试之后,似乎第一个测试向 ActionMailer::Base.deliveries 数组添加了一个项目,并且该项目从未被清除。这会导致测试中的第一行失败,因为数组不是空的。
在 RSpec 测试之后清除 ActionMailer::Base.deliveries 数组的最佳方法是什么?
【问题讨论】:
为什么不应该在您的setup
块中使用ActionMailer::Base.deliveries = []
?
此规范是否位于spec/mailers/
?
【参考方案1】:
RSpec.describe UserMailer do
before do
# ActionMailer::Base.deliveries is a regular array
ActionMailer::Base.deliveries = []
# or use ActionMailer::Base.deliveries.clear
end
it "sends welcome email" do
user = create(:user)
UserMailer.welcome_email(user).deliver_now
expect(ActionMailer::Base.deliveries).to be_present
end
end
【讨论】:
为了避免重复,你可以把它放在spec_helper.rb的config块中:config.before(:each) ActionMailer::Base.deliveries.clear
这不是必需的,因为应该设置 RSpec 邮件规范以自动清除交付数组。详情请见github.com/rspec/rspec-rails/issues/661。
它应该适用于邮件规范,但不适用于请求规范 - 然后你需要以某种方式自己清除它。我?我要使用 Luke Francl 方法。【参考方案2】:
正如安迪·林德曼(Andy Lindeman)所指出的,对于邮件测试,清理交付是自动完成的。但是,对于其他类型,只需将 , :type => :mailer
添加到包装块即可强制执行相同的行为。
describe "tests that send emails", type: :mailer do
# some tests
end
【讨论】:
感谢您的提示!这对我来说感觉像是一种更清洁的方法。适用于 Rails 4.1 和 Rspec 3.1。 是的。这是我遇到的问题。我忘了加type: :mailer
。谢谢 d_rail!
这对我来说似乎很脆弱。用特殊标志装饰测试用例,使它们以不明显的方式运行。我更喜欢其他答案。
将“mailer”标签添加到并非专门为 mailer 单元测试的测试似乎已损坏。我宁愿选择其他方法之一。【参考方案3】:
您可以在每次测试后轻松清除交付,将其添加到您的 spec_helper.rb 中。
RSpec.configure do |config|
config.before ActionMailer::Base.deliveries.clear
end
我建议阅读我关于 correct emails configuration in Rails 的文章,其中我还谈到了正确测试它们。
【讨论】:
这似乎是迄今为止最清晰的解决方案。对于使用 email-spec 的项目,请考虑在 before 块中调用reset_mailer
来代替 ActionMailer::Base.deliveries.clear
,因为 reset_mailer
会做一些额外的工作,这可能会有所帮助。 RSpec.configure do |config| config.before(:each) reset_mailer end
以上是关于在 RSpec 测试后清除 ActionMailer::Base.deliveries的主要内容,如果未能解决你的问题,请参考以下文章