You don't always need a custom matcher to write clean RSpec tests

Posted . Visible to the public.

When you repeat complex assertions in your tests multiple times, it might be a good idea to extract a custom RSpec matcher. This not only tidies up your own code, but also makes it easier to write future specs.

However, not all situations are well-suited for that. Sometimes the effort isn't worth it, e.g. when your matcher would need too many parameters to be reusable. In those cases, you can also simply extract a private method:

describe `/search` do
  it "doesn't lose the infinite scroll's filter state when navigating backwards" do
    create(:event, :published, name: '1st match', start_date: 1.week.from_now)
    create(:event, :published, name: '2nd match', start_date: 1.week.from_now)
    create(:event, :published, name: 'Discarded', start_date: 2.years.from_now)

    visit(search_path(start_date: 'next_3_months'))

    expect_item_card_to_contain('1st match')
    expect_infinite_scroll_to_be_filtered

    within('.layout--infinite-scroll') do
      click_link('2nd match')
    end

    expect_item_card_to_contain('2nd match')
    expect_infinite_scroll_to_be_filtered

    within('.layout--infinite-scroll') do
      click_link('1st match')
    end

    expect_item_card_to_contain('1st match')
    expect_infinite_scroll_to_be_filtered

    page.go_back

    expect_item_card_to_contain('2nd match')
    expect_infinite_scroll_to_be_filtered

    page.go_back

    expect_item_card_to_contain('1st match')
    expect_infinite_scroll_to_be_filtered
  end

  private

  def expect_infinite_scroll_to_be_filtered
    within('.layout--infinite-scroll') do
      expect(page).to have_text('1st match')
      expect(page).to have_text('2nd match')
      expect(page).not_to have_text('Discarded')
    end
  end

  def expect_item_card_to_contain(text)
    within('.layout--item-card') do
      expect(page).to have_text(text)
    end
  end
end
Klaus Weidinger
Last edit
Klaus Weidinger
License
Source code in this card is licensed under the MIT License.
Posted by Klaus Weidinger to makandra dev (2025-07-10 08:58)