Configure & Add Test Factories

Workarea allows you to extend its test factories to suit your application.

This document provides recipes to Configure a Test Factory and Add a Test Factory.

Configure a Test Factory

Each factory method uses a configurable set of default values to generate a model instance when no custom values are provided. Default values are either a Hash or a Proc instance that returns a hash consisting of values that are determined at the time the method is called. A Proc is executed within the context of the Workarea::Factories module, allowing access to other factory methods to generate default values like associations or ensure a unique name is generated for each model instance generated by the factory method.

Workarea.configure do |config|
  config.testing_factory_defaults.inventory =
    { id: 'SKU', policy: 'standard', available: 5 }

  config.testing_factory_defaults.audit_log_entry = Proc.new do
    { modifier: create_user, audited: create_page }
  end

  config.testing_factory_defaults.shipping_service = Proc.new do
    { name: "Test #{shipping_service_count}", rates: [{ price: 1.to_m }] }
  end
end

These default values can be customized for your application to modify the default model instances across the entire test suite without having to decorate each individual test. A common use case would be adding a default value for a field that your application requires but is not required out of the base Workarea model (e.g. phone number on shipping address).

You can customize these values in your application's test_helper.rb

# Modify the configuration for factory default values
# test/test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__ )
require 'rails/test_help'
require 'workarea/test_help'

Workarea.configure do |config|
  config.testing_factory_defaults.shipping_address[:phone_number] = '2155551212'
end

Additionally, you can customize the factory default values for the duration of a single test.

Since Workarea 3.5.0, the global configuration is reset before each test. Prior to Workarea 3.5.0, you must wrap temporary configuration changes in Workarea.with_config to ensure they reset after the test.

Example for Workarea 3.5 and up:

# test/system/storefront/categories_system_test.decorator

require 'test_helper'

module Workarea
  decorate Storefront::CategoriesSystemTest do

    # Decorate setup method
    def set_products
      config.testing_factory_defaults.product.merge!(
        # add customized defaults
      )

      super
    end
  end
end

Example for Workarea versions prior to 3.5:

# test/system/storefront/categories_system_test.decorator

require 'test_helper'

module Workarea
  decorate Storefront::CategoriesSystemTest do

    # Decorate setup method
    def set_products
      Workarea.with_config do |config|
        config.testing_factory_defaults.product.merge!(
          # add customized defaults
        )

        super
      end
    end
  end
end

Add a Test Factory

To create a new factory (e.g. to support a new model unique to your application), create new module within the Factories namespace, register the new factory using Factories.add(self), and define the factory methods you need.

For example:

# <application_root>/test/factories/entertainment.rb

module Workarea
  module Factories
    module Entertainment

      Factories.add(self)

      def create_calendar(overrides = {})
        attributes = { name: 'Test Calendar' }.merge(overrides)
        Workarea::Entertainment::Calendar.create!(attributes)
      end

      def foo_bar
        # ...
      end

      # ...
    end
  end
end

Then, require the new module from your test helper:

# <application_root>/test/test_helper.rb

ENV['RAILS_ENV'] ||= 'test'

# ...

require 'factories/entertainment'

Now you can use the new factory methods within all tests that include factories.

Now on GitHub