Skip to content

Getting started

Kevin Sjöberg edited this page Aug 11, 2017 · 4 revisions

Blacksmith is an easy-to-use fixtures replacement that allows you to programatically define objects for testing and development purposes. It's an alternative to factory_girl.

The easiest way to get started is by adding Blacksmith to your Gemfile.

gem "blacksmith", "~> 1.0"

If you're using Ruby on Rails, you should be using blacksmith_rails instead.

gem "blacksmith_rails", "~> 1.0"

Forges

Forges are used to define your test objects. A forge is simply a class inheriting from Blacksmith::Forge. Following good testing practices they should be defined in either test/forges or spec/forges depending on your test framework.

Let's define a forge for our imaginary User class.

class UserForge < Blacksmith::Forge
  def default
    forgeable do |user|
      user.name = "Jon Snow"
      user.email_address = "jon.snow@example.com"
    end
  end
end

This is the basic structure of a forge. Methods in the class describe your test objects and you're free to create as many of these as you like. default is, as you can imagine, the default test object for the given forge.

Let's try it out in a test.

class TestUser < Minitest::Test
  include Blacksmith::Tooling

  def setup
    @forge = UserForge.new(User)
  end

  def test_full_name
    user = make @forge.default
    assert_equal "Jon Snow", user.full_name
  end
end

We can simplify this further. In setup we initialized our user forge by doing UserForge.new(User). By setting a default creator for our forge, we can skip this step entirely.

class UserForge < Blacksmith::Forge
  def initialize(creator = User)
    super(creator)
  end
    
  def default
    forgeable do |user|
      user.name = "Jon Snow"
      user.email_address = "jon.snow@example.com"
    end
  end
end

Let's also make use of the forge helper from Blacksmith::Tooling. Our test can now be rewritten as follows.

class TestUser < Minitest::Test
  include Blacksmith::Tooling

  def test_full_name
    user = make forge(:user)
    assert_equal "Jon Snow", user.full_name
  end
end

As you can see, we now referenced our user forge by calling forge(:user). Note that we didn't have to call default explicitly. forge does that for us if we don't tell it otherwise.

Tools

Blacksmith comes with some handy set of tools. These live in Blacksmith::Tooling and currently consists of make, make_list and forge.

make

make is the number of most important tool of Blacksmith. It allows you to create the actual test objects:

user = make UserForge.new(User).default

In fact, we can even shorten this, since make will call the default factory for us:

user = make UserForge.new(User)

You can override attributes on the fly:

user = make UserForge.new(User), name: "Tyrion Lannister"

You can even pass it a block, yielding the test object itself:

make UserForge.new(User) do |user|
  user.confirmed_at = Time.now
end

make_list

make_list is merely a thin wrapper around make. It allows you to create a collection of test objects, given by a number.

users = make_list UserForge.new(User), 2

You can override attributes on the fly:

users = make_list UserForge.new(User), 2, confirmed_at: Time.now

You can even pass it a block, yielding the collection of test objects:

users = make_list UserForge.new(User), 2 do |users|
  users.map(&:confirm!)
end

forge

forge allows you to reference a specific forge implicitly without worrying about class name or initialization. It becomes very handy as your arsenal of forges starts to grow.

user = make forge(:user)

It also supports polymorphism by allowing you to specify a custom creator on the fly:

user = make forge(:user, Admin)
Clone this wiki locally