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? .)