Rails Minitest使用assert_select报document_root_element错误是什么原因?
错误含义
assert_select 方法默认需要一个根DOM节点作为查询范围,当你在非控制器/集成测试场景下直接调用无前置根节点的assert_select时,Rails的Dom测试模块会尝试调用测试类的document_root_element方法获取默认根节点,你没有实现该方法就会触发这个NotImplementedError异常。
解决方案
提供两种常用的解决方式,按需选择:
方式1:实现document_root_element方法,适配全局默认调用
适合测试类中所有用例都需要统一从同一根节点查询的场景,示例代码如下:
class MyEmailBodyGeneratorTest < ActiveSupport::TestCase include Rails::Dom::Testing::Assertions # 存储要查询的根DOM节点 attr_accessor :root_node # 实现框架要求的document_root_element方法 def document_root_element root_node end def test_generate_email_body generator = MyEmailBodyGenerator.new # 获取生成的HTML字符串 generated_html = generator.generate_email_body # 解析HTML为DOM节点赋值给root_node self.root_node = Nokogiri::HTML5.parse(generated_html) # 直接正常调用assert_select即可 assert_select 'p.salutation', count: 1 end end
方式2:直接给assert_select指定查询根节点
适合每个测试用例需要单独指定查询范围的场景,无需额外定义方法,修改测试用例代码即可:
class MyEmailBodyGeneratorTest < ActiveSupport::TestCase include Rails::Dom::Testing::Assertions def test_generate_email_body generator = MyEmailBodyGenerator.new generated_html = generator.generate_email_body # 解析得到根节点 root = Nokogiri::HTML5.parse(generated_html) # 第一个参数传入根节点,指定查询范围 assert_select root, 'p.salutation', count: 1 end end
如果生成的是HTML片段而非完整文档,也可以用Nokogiri::HTML5.fragment(generated_html)解析,不影响选择器查询效果。
内容的提问来源于stack exchange,提问作者Jon Schneider
相关产品推荐
相关产品推荐

