Extending Faker

Posted on by Adam Dunson

Faker is a Ruby library designed to generate various types of fake data, including, among several others, realistic "names, addresses, and phone numbers." It uses I18n locales for storing the fake data strings and formats, and out of the box, it provides the ability to set the locale via the Faker::Config.locale attribute. However, it is also possible to extend the Faker::Base class if you want to generate realistic fake data for a data structure that the base gem doesn't support.

HEY EVERYBODY THIS GUY'S A GREAT, BIG PHONY!

Extending Faker isn't difficult; there are really only three steps. First, you'll need to write the YAML for your custom class and fill it with the data you want to fake. For instance, here is an example that sets up a Beer class with various styles and names. It utilizes some of the classes provided by Faker (Name and Commerce) to generate the Beer names.

# config/locales/faker.en.yml
en:
  faker:
    beer:
      style: [American Amber / Red Ale, American Barleywine, American Black Ale, American Blonde Ale, American Brown Ale, American Dark Wheat Ale, American Double / Imperial IPA, American Double / Imperial Stout, American IPA, American Pale Ale (APA), American Pale Wheat Ale, American Porter, American Stout, American Strong Ale, American Wild Ale, Black & Tan, Chile Beer, Cream Ale, Pumpkin Ale, Rye Beer, Wheatwine, Belgian Dark Ale, Belgian IPA, Belgian Pale Ale, Belgian Strong Dark Ale, Belgian Strong Pale Ale, Bière de Champagne / Bière Brut, Bière de Garde, Dubbel, Faro, Flanders Oud Bruin, Flanders Red Ale, Gueuze, Lambic - Fruit, Lambic - Unblended, Quadrupel (Quad), Saison / Farmhouse Ale, Tripel, Witbier, Baltic Porter, Braggot, English Barleywine, English Bitter, English Brown Ale, English Dark Mild Ale, English India Pale Ale (IPA), English Pale Ale, English Pale Mild Ale, English Porter, English Stout, English Strong Ale, Extra Special / Strong Bitter (ESB), Foreign / Export Stout, Milk / Sweet Stout, Oatmeal Stout, Old Ale, Russian Imperial Stout, Winter Warmer, Altbier, Berliner Weissbier, Dunkelweizen, Gose, Hefeweizen, Kölsch, Kristalweizen, Roggenbier, Weizenbock, Irish Dry Stout, Irish Red Ale, Scotch Ale / Wee Heavy, Scottish Ale, Scottish Gruit / Ancient Herbed Ale, American Adjunct Lager, American Amber / Red Lager, American Double / Imperial Pilsner, American Malt Liquor, American Pale Lager, California Common / Steam Beer, Light Lager, Low Alcohol Beer, Czech Pilsener, Sahti, Kvass, Euro Dark Lager, Euro Pale Lager, Euro Strong Lager, Bock, Doppelbock, Dortmunder / Export Lager, Eisbock, German Pilsener, Keller Bier / Zwickel Bier, Maibock / Helles Bock, Märzen / Oktoberfest, Munich Dunkel Lager, Munich Helles Lager, Rauchbier, Schwarzbier, Vienna Lager, Happoshu, Japanese Rice Lager, Fruit / Vegetable Beer, Herbed / Spiced Beer]
      name:
        - "#{Name.first_name} #{style}"
        - "#{Name.first_name}'s #{style}"
        - "#{Name.last_name} #{style}"
        - "#{Name.last_name}'s #{style}"
        - "#{Commerce.product_name.adjective} #{style}"

List of beer styles from http://beeradvocate.com/beer/style

Next, you'll extend the Faker::Base class. In my case, I wrote the following class:

# lib/faker/beer.rb
module Faker
  class Beer < Base
    class << self
      def name
        parse('beer.name')
      end

      def style
        fetch('beer.style')
      end
    end
  end
end

This class uses the fetch and parse methods of Faker::Base. Here, fetch returns a random style from the array of beer styles (using Array.sample). Similarly, parse calls fetch, and then interpolates the string by replacing, e.g., "#{Name.last_name}'s #{style}" with "Herzog's Witbier".

Finally, you'll need to require your new library (or add it to your app's config.autoload_paths) before you can use it.

2.0.0p247 :001 > require Rails.root.join 'lib/faker/beer'
 => true
2.0.0p247 :002 > Faker::Beer.name
 => "Willy's English India Pale Ale (IPA)"

Custom Faker classes are useful for creating more attractive demos and mock-ups. I've also seen it used with gems like factory_girl to generate random test data, though the benefits of this pattern are questionable.

If you've got any questions, I'm happy to answer them!

Sláinte!

 
comments powered by Disqus