---
title: Taming Factory Bot List Creation
teaser:
tags: web,ruby,testing,factory_girl,factory_bot
author: Derek Prior
published_on: 2013-07-13
---

There are times in your tests when you need to create multiple instances of the same type
of object. FactoryBot[^1] provides [`create_list`][create_list] for just these
sorts of scenarios. It's typically sufficient to create two records in these
cases, but `create_list` leaves open the possibility that you could
unintentionally create many more records.

Consider, for example, testing a feature that pages in additional records on
demand. You would likely want to use something like [Kaminari] to expose the
paging functionality. We did just this on a recent project.

    scenario 'user can page in additional records' do
      posts = create_list(:post, Post.default_per_page + 1)

      click_button "Load More"

      expect(page).to have_content(posts.first.body)
      expect(page).to have_content(posts.last.body)
    end

The trouble is that Kaminari defaults the `default_per_page` value to 25. This
test will create 26 records in your database. Seems a bit much, no? The simplest
way to solve this is to stub the `Post.default_per_page` method in the test, but
you will have to remember to do this in every place you test paging. Not so bad
if you're only paging `Post`, but what about `Comment`, `Author`, etc?

## Sane Kaminari Defaults in Test

The first step we took towards solving this was to introduce
an initializer that defaults the Kaminari page size to 1 record in the test environment.

    Kaminari.configure do |config|
      if Rails.env.test?
        config.default_per_page = 1
      end
    end

This works great until someone comes along and overrides the default page size
on `Post` with `paginates_per(20)`. Now you're back to creating 21 records in
your test or having to remember to stub the `default_per_page` method on models
that override the Kaminari default.

## A Safety Net: Let's Patch Factory Bot

The application we're working on has a lot of paging. I half-jokingly
suggested we override `create_list` to prevent gigantic list creation. When
the idea wasn't met with immediate guffaws, I went to work. I added the
following to our FactoryBot configuration that is required from
`spec_helper`:

```ruby
require 'factory_bot_rails'

module FactoryBot
  module Syntax
    module Methods
      alias_method :original_create_list, :create_list

      def create_list(name, amount, *traits_and_overrides, &block)
        if amount > 2
          raise ArgumentError, "You asked to create #{amount} records. Don't do that."
        end

        original_create_list(name, amount, *traits_and_overrides, &block)
      end
    end
  end
end

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
```

Calls to `create_list` will now raise if you attempt to create more than two
records. In the case of our paging example, this signals that we forgot to stub
the `defaults_per_page` method.  If you have a legitimate need to create more
than two records, you can call `original_create_list`.

Interestingly, this change surfaced a number of non-paging tests that were
creating three records where even just one would do.

[create_list]: https://thoughtbot.github.io/factory_bot/building-or-creating-multiple-records/summary.html
[kaminari]:https://github.com/amatsuda/kaminari

[^1]: Looking for FactoryGirl? The library was renamed in 2017.
[Project name history can be found here.](https://github.com/thoughtbot/factory_bot/blob/master/NAME.md)
