United Kingdom: +44 (0)208 088 8978

Bogus on F#

What is Bogus?

Bogus, as its author describes it, is a simple and sane fake data generator for .NET languages. It’s used by many popular projects such as Elasticsearch .NET Client (NEST), GraphQL for .NET, and more. Whether you need example data for testing a CRUD application or just some placeholders for a demo, Bogus got your back!

Bogus is very easy to use, yet it can be very powerful. In this blogpost, I will demonstrate how easy it is to set up, and give a couple of examples in one of the three ways that it can be used. To explore alternative ways to use it and to find out the full extent of its capabilities, I recommend you visit its official GitHub repo.

The first step, as with any other third-party library, is to add it to your project. So, please do so before moving on if you intend to follow along with the code.

A Simple Use Case

Now, let’s say that you have the following type in our domain, for which you’d like to generate many instances.

type Customer =
  { FullName : string
    PhoneNumber : string
    Street : string
    City : string
    PostCode : string
    Country : string }

In order to be able to generate data, you will need a Faker instance, and here's how to create one:

open Bogus
let faker = Faker "en"

Here, I’m using a locale code of en, which stands for “English”.

Next, is to use this instance to generate data for each field of our record, and for your convenience, you may want to create a function which you can reuse for this:

let generateCustomer() =
  { FullName = faker.Name.FullName()
    PhoneNumber = faker.Phone.PhoneNumber()
    Street = faker.Address.StreetAddress()
    City = faker.Address.City()
    PostCode = faker.Address.ZipCode()
    Country = faker.Address.Country() }

The Faker object has a multitude of methods that each generates a different type of data. I used a handful of them here (Name.FullName, Phone.PhoneNumber, etc.), but you can find the full list of methods at the Bogus GitHub page.

And there you have it! With all this in place, generating a random customer is as easy as calling the generateCustomer function. Do you need a list of a hundred customers? Easy.

[ for i = 1 to 100 do generateCustomer() ] 

The Possibilities

Make no mistake about it. Though Bogus is as straightforward as packages get, it will cover all of your data generation needs no matter how complicated your domain is. This is probably evident from the example I’ve just shown, but I will go on to give a more complex example just to drive the point home.

Consider the following domain:

type Gender = Male = 1 | Female = 2 | Other = 3

type EmailProvider = Outlook = 1 | Gmail = 2 | Yahoo = 3

type Customer =
  { FullName : string
    Username : string
    EmailProvider : EmailProvider
    Gender : Gender }

type Order = 
  { Id : Guid
    Customer : Customer
    Delivered : bool }

Also, consider that using these types, we will store several orders in a document database, each of which will have a nested customer. We want to seed the database, and to save time, we want to use Bogus to generate all this data for us.

Here's a simple way of doing this:

open Bogus
let faker = Faker "en"

let orders =
  let customers =
    [ for i = 0 to 10 do 
      { FullName = faker.Name.FullName()
        Username = faker.Internet.UserName()
        EmailProvider = faker.PickRandom<EmailProvider>()
        Gender = faker.PickRandom<Gender>() } ]

  [ for i = 0 to 100 do 
    { Id = faker.Random.Guid()
      Customer = faker.PickRandom(customers) 
      Delivered = faker.Random.Bool() } ]

As you can see, I’m first creating a list of 10 customers and binding it to customers. Below that, I am creating a hundred orders, and for each order, I am randomly picking a customer from customers and nesting it inside the order. I am then binding the final result to orders.

And there we have it. A list of orders, each of which has one of ten pre-defined customers as one of its fields.

Closing Thoughts

I hope you enjoyed this blogpost and I was able to bring value to you! To me, Bogus is one of the most essential packages. Especially for CRUD applications. Not because you will be using it very frequently all throughout a project, but because for the brief moment that you’ll need it, it will save you a lot of time and effort.