How to generate Fake data in C#?

The reason for generating fake data can be anything. But, the most common use case I think for generating fake data is when someone is dependent on the result from your API.

As a backend developer, you’ve to just create a model and return a few fake objects that represent data.

We could however create a new object of the new model but what if we’ve to do it for several models and multiple API endpoints. This will be tiresome to do it yourself.

Let’s say we have an API that should return a customer object when provided with an id of the customer.

Here is our customer model.

    public class Customer
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Bio { get; set; }
        public Address Address { get; set; }
    }

    public class Address
    {
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string PinCode { get; set; }
    }

Now, if we want to generate fake data we will have to set some random text to our string types and a number to the integer type.

I think it’s time to find a fake/dummy data generator.

Bogus is one such fake data generator for C#, F#, and VB.NET. It is inspired by faker.js (a popular library for creating fake data in JavaScript).

Currently Bogus supports

  • .NET 6.0
  • .NET Standard 1.3 or higher
  • .NET Framework 4.0 or higher

Setup Bogus

Install Bogus from Nuget with the following command

Install-Package Bogus

How to work with Bogus

  • Pass your class type as a parameter to the Faker class.
  • Call .Generate() method on the Faker object to generate some random data. That’s it!

Ex:

var data = new Faker<T>();
var output = data.Generate();

How to generate fake data with Bogus?

Let’s see how the Bogus generates data for us without assigning any rules for the Faker object.

Here is my Main method code.

class Program
{
    static void Main(string[] args)
    {
        var customer = new Faker<Customer>();

        Console.WriteLine(customer.Generate().Dump());
    }
}

Note: the Dump is an extension method that I’ve created which takes any object and serializes the object to JSON with indentation.

And here is the output of the above code

{
  "Id": 0,
  "FirstName": null,
  "LastName": null,
  "Email": null,
  "Bio": null,
  "Address": null
}

With no rules for data, we can see the Bogus returned object properties with default values for the types.

Generating fake data for the types using rules in Bogus

Let’s write rules for all of our fields and see how the test data is generated

var address = new Faker<Address>()
                .RuleFor(a => a.Line1, f => f.Address.BuildingNumber())
                .RuleFor(a => a.Line2, f => f.Address.StreetAddress())
                .RuleFor(a => a.PinCode, f => f.Address.ZipCode())
              ;

var customer = new Faker<Customer>()
        .RuleFor(c => c.Id, f => f.Random.Number(1, 100))
        .RuleFor(c => c.FirstName, f => f.Person.FirstName)
        .RuleFor(c => c.LastName, f => f.Person.LastName)
        .RuleFor(c => c.Email, f => f.Person.Email)
        .RuleFor(c => c.Bio, f => f.Lorem.Paragraph(1))
        .RuleFor(c => c.Address, f => address.Generate())
    ;
Console.WriteLine(customer.Generate().Dump());

Notice how we created rules for fields. Also observe Address, Person, Random, Lorem these are supported by Bogus API itself so that we can create the context based fake data instead of generating random text for the fields.

And here is the output.

{
  "Id": 61,
  "FirstName": "Erica",
  "LastName": "Tremblay",
  "Email": "[email protected]",
  "Bio": "Impedit est dicta ad. Magnam molestiae debitis nemo recusandae dolor aut alias.",
  "Address": {
    "Line1": "61934",
    "Line2": "140 Angela Flats",
    "PinCode": "27723-1415"
  }
}

This looks great!

Let’s say we want to generate data by type and not for every field. Let’s see how we can do it.

Generating fake data by Type

var address = new Faker<Address>()
            .RuleForType(typeof(string), c => c.Random.AlphaNumeric(50))
            ;

var customer = new Faker<Customer>()
         .RuleForType(typeof(string), c => c.Random.Word())
        .RuleForType(typeof(int), c => c.Random.Number(10, 20))
        .RuleFor(c => c.Email, f => f.Person.Email)
        .RuleFor(c => c.Address, f => address.Generate())
    ;

Console.WriteLine(customer.Generate().Dump());

Here’s the output

{
  "Id": 20,
  "FirstName": "Aruba",
  "LastName": "data-warehouse",
  "Email": "[email protected]",
  "Bio": "Markets",
  "Address": {
    "Line1": "2scvd7yl26uxpp28nr9k6aizk8sishmohliglkgsi3v4ykvt0y",
    "Line2": "4cntrrada4egtkj6g37mn3ag12fd10czhtda0ntr689cd2aaks",
    "PinCode": "3smdb016sobwcasfy0795safgfuy3ys4s9wkd4hc8tv4f9vyjy"
  }
}

Although the strings for Address fields are not readable, we can see how we got random string with alpha numeric characters for address fields.

 The order of the rules matters

Notice how the above customer query is built.

var customer = new Faker<Customer>()
                     .RuleForType(typeof(string), c => c.Random.Word())
                    .RuleForType(typeof(int), c => c.Random.Number(10, 20))
                    .RuleFor(c => c.Email, f => f.Person.Email)
                    .RuleFor(c => c.Address, f => address.Generate())
                ;

Though we set up all the string types to use Random.Word() method to generate a random word we still got an Email address in the output because of the next rule for the Email field

.RuleFor(c => c.Email, f => f.Person.Email)

So, if we’ve moved the email rule to the top and have the RuleForType string at the end. Then all the strings would’ve generated random words including the email field.

Generating collections of fake data

var customer = new Faker<Customer>();
var customerList = customer.Generate(3);

Passing the number of items to create in the collection will produce List<Customer> object.

With non-fluent syntax

Bogus also provides non-Fluent syntax so you can create a Faker object without providing any class type and generate the fake data. Here’s an example of how we can do it.

Var faker = new Faker("en");
Var email = faker.Person.Email;

Misc: The Dump() extension method

This is the .Dump() method used to serialize the object to produce JSON in this blog post.

using Newtonsoft.Json;
public static string Dump(this object obj)
{
    return JsonConvert.SerializeObject(obj, Formatting.Indented);
}

References

  1. Bogus
  2. Faker.js