如何解决Rails Minitest+Capybara邮件测试的ActionView::Template host错误?
问题根源
两次报错都是邮件模板渲染失败引发的连锁问题:
- 第一轮报错是测试环境没有配置邮件服务的默认域名,后台异步发送邮件时没有请求上下文可以自动获取域名,导致模板内的链接生成失败,邮件根本没有被创建,所以
ActionMailer::Base.deliveries为空,取last得到nil调用to方法自然报错。 - 你添加域名配置后,又触发了第二个路由错误:你的项目路由配置了
locale前缀参数,而app/views/line_items/_line_item.html.erb第13行生成line_item链接时,没有显式传递locale参数,导致系统把你传入的LineItem对象识别为locale参数,缺失了必填的id参数,模板再次渲染失败,邮件还是没有生成,所以依然报nil调用to的错误。
开发环境不需要显式配置default_url_options是因为Rails开发模式会自动从当前请求中提取域名作为默认值,而测试环境、后台异步任务都没有请求上下文,无法自动获取。
修复方案
按以下步骤操作即可解决:
- 修复路由参数问题
打开app/views/line_items/_line_item.html.erb第13行,调整链接生成代码:- 如果你的路由
locale为必填参数,修改链接代码为类似line_item_path(I18n.locale, line_item)的形式,显式传入locale参数 - 如果你的路由
locale为可选参数,可在路由配置中给locale添加默认值,示例:
# config/routes.rb scope "(:locale)", locale: /en|zh/ do # 原有路由配置 end - 如果你的路由
- 完善测试环境邮件配置
确认config/environments/test.rb中包含以下配置:
config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { host: 'www.example.com' }
- (可选)如果邮件内的链接不需要全路径域名,可在所有
link_to参数中添加only_path: true,即可不用配置default_url_options。
改完后重新运行测试,邮件模板可正常渲染,ActionMailer::Base.deliveries会正常存储生成的邮件,后续断言即可正常执行。
内容的提问来源于stack exchange,提问作者jbk
相关产品推荐
相关产品推荐

