View specs: rendering templates that are nested within a view component

Posted by on 30 June 2025

FreeAgent makes use of the RSpec and ViewComponent frameworks for unit testing and reusable front-end components respectively.

Since FreeAgent is a Ruby on Rails application, we’ll often want to write unit tests for our Rails view templates, using RSpec, i.e., a view spec.

When rendering our reusable view components in our view templates, especially complex ones, testing can get a bit confusing, especially if the template is dependent on being rendered within the context of a view component.

E.g., suppose you want to write a view spec for _row.html.erb, which is rendered in another view below.

<% # _table.html.erb %>
<%= render TableComponent.new do |table| %>
  <% @employees.each do |employee| %>
    <% table.with_row do |row| %>
       <%= render "row", employee: employee, row: row %>
    <% end %>
  <% end %>
<% end %>

<% # _row.html.erb %>
<% row.with_cell do %>
  <div data-testid="employee_1">
    <p>Some content</p>
  </div>
<% end %>

It turns out that in the view spec, you can include ViewComponent::TestHelpers to get access to view component helpers, e.g., render_inline which is useful for setting up a test case.

RSpec.describe "_row", type: :view do
  include ViewComponent::TestHelpers

  let(:employee) { build_stubbed(:employee) }

  subject do
    render_inline(Table::RowComponent.new(context: :tbody, position: 1)) do |row|
      render partial: "employees/_row", locals: { employee:, row: }
    end
  end

  it { is_expected.to have_content "Some content" }
end

An extra tip: to avoid testing the wrapping components, scoping the tested content using an attribute like testid can be helpful.

subject do
  row = render_inline(Table::RowComponent.new(context: :tbody, position: 1)) do |row|
    render partial: "employees/_row", locals: { employee:, row: }
  end

  row.find "[data-testid='employee_#{employee.id}']"
end

So there you have it! Next time you’re trying to write view specs for your components, consider adding the TestHelpers module.

Leave a reply

Your email address will not be published. Required fields are marked *