Home > Software engineering >  Rails Minitest: Error about "document_root_element" when trying to use assert_select
Rails Minitest: Error about "document_root_element" when trying to use assert_select

Time:09-28

In a Rails app, I'm writing Minitest unit tests for a helper class which generates and returns some HTML (to be used as the body content of an outgoing email message). I'm using assert_select to verify that a particular element is present in the generated HTML.

When the test is run, the line with the assert_select throws this error:

Minitest::UnexpectedError: NotImplementedError: Implementing document_root_element makes assert_select work without needing to specify an element to select from.

Here's my (minimal/simplified) test class code:

class MyEmailBodyGeneratorTest < ActiveSupport::TestCase
  include Rails::Dom::Testing::Assertions

  def test_generate_email_body
    generator = MyEmailBodyGenerator.new
    generator.generate_email_body

    assert_select 'p.salutation', count: 1
  end
end

What does that error about implementing document_root_element mean? I don't have a method with that name in my code.

CodePudding user response:

This error is happening because the test isn't (in more typical Rails fashion) making an HTTP request to a Rails controller, and therefore, assert_select doesn't automatically know what HTML to inspect, since there's no HTML response.

As the error message suggests, you can fix this by implementing a method named document_root_element in your test class, and having it return the root node of the HTML that you want inspected. For example:

class MyEmailBodyGeneratorTest < ActiveSupport::TestCase
  include Rails::Dom::Testing::Assertions

  def test_generate_email_body
    generator = MyEmailBodyGenerator.new
    @email_body_html = generator.generate_email_body

    assert_select 'p.salutation', count: 1
  end

  def document_root_element 
    Nokogiri::HTML::Document.parse(@email_body_html)
  end
end

(For more on parsing a string containing HTML into a tree of objects representing the elements in the HTML, see Method to parse HTML document in Ruby? .)

  • Related