Follow me: Jack Histon's Twitter Share on LinkedIn Share on Google+ RSS Feed

Author avatar

Welcome. I am Jack Histon. My career would not be what it is today without dedication and hard work from software bloggers. My purpose is to give back to that online community.

How to Create Bogus Data in C#

Sunday, 01 October 2017

Tweet about this on Twitter Share on Facebook Share on LinkedIn Share on Google+ Pin on Pinterest Share on Reddit Share on StumbleUpon

Programmers are lazy. We love tools that automate our lives. Why not automate data?

A time-consuming but necessary part of a programmers job is seeding data into a database. Demonstrations, load performance, styling, testing, all need a way to generate data. A rudimentary way of doing this is by hand. Spending days, sometimes weeks, inputting data into a system until it represents a realistic go-live scenario.

Once you begin to realise doing it by hand is inefficient, you decide to create a seeding application that does it for you. One of the fundamental problems of seeding, and a general problem in computer science in general, is generating random data. You spend time understanding how to randomize dates, generate lorem ipsum text, create default images, and so on.

After a while, you again realise that building this seeding application is taking a long time. You realise that seeding must be a problem many other programmers face? You search the internet on a quest to make it easier. You find Bogus.

What is Bogus?

The quote Brian Chavez provides, aptly describes Bogus:

Bogus is a simple and sane fake data generator for .NET languages like C#, F# and VB.NET

Bogus helps create seeding applications. Bogus sorts out all the annoyances with randomising data, and allows you to generate classes again and again.

Bogus is based on faker.js, another framework that helps generate massive amounts of fake data in node.js and browsers.

Bogus provides many default types of data. As you expect, the simple data types in C# are all covered, such as datetime, bool, int, etc. Bogus also provides an API that is situational. For example, Bogus has APIs that allow you to generate data for Commerce scenarios, such as product names, category names, pricing, and so on.

Generating Blog Data

This blogging website uses Entity Framework. With Entity Framework, you have to create entities. Entities represent tables within your database, and are the interaction point for inserting data into it. The following example shows the entity used by this website for a blog post:


public class BlogPost
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public string MetaDescription { get; set; }
    public string Keywords { get; set; }
    public bool IsActive { get; set; }

    public DateTime Created { get; set; }

    public string AuthorId { get; set; }
    public ApplicationUser Author { get; set; }

    public List Tags { get; set; }

    public BlogPost()
    {
        Tags = new List();
    }
}

Entities in entity framework are plain old CLR objects (POCO), that is, very simple objects with no logic code or inheritance.

With this class, we will tell Bogus a few rules in order to generate a sample blog post:


var testBlogPosts = new Faker<BlogPost>()
    .RuleFor(bp => bp.Id, f => f.IndexFaker)
    .RuleFor(bp => bp.Content, f => f.Lorem.Paragraphs())
    .RuleFor(bp => bp.Created, f => f.Date.Past())
    .RuleFor(bp => bp.IsActive, f => f.PickRandomParam(new bool[] { true, true, false }))
    .RuleFor(bp => bp.MetaDescription, f => f.Lorem.Sentences(3))
    .RuleFor(bp => bp.Keywords, f => string.Join(", ", f.Lorem.Words()))
    .RuleFor(bp => bp.Title, f => f.Lorem.Sentence(10))
    .RuleFor(bp => bp.Tags, f => fakeBlogPostTags.Generate(3).ToList())
    .FinishWith((f, bp) => Console.WriteLine($"Blog post created. Id={bp.Id}"));

On the first line, we have used the main feature of the Bogus framework: the faker. The faker is used to generate fake objects. Here we can see that we have define multiple rules for generating a blog post.

The rule syntax uses a fluent interface. A fluent interface is a way to chain method calls for configuration. It is classically used within the builder design pattern.

The first rule defines that the Id of the blog post should be the currnet index of a faker. When you generate a blog post, this index is incremented.

The second rule shows off lorem ipsum generation. You can specify if you want words, sentences, paragraphs, and you can also describe how many you want to generate. This is great for when you want to create some demonstration data for showcasing.

Another interesting rule is the last:


.RuleFor(bp => bp.Tags, f => fakeBlogPostTags.Generate(3).ToList())

This is using another faker object to generate tags for the blog post. Here is the rest of the fakers:


var fakeTags = new Faker<Tag>()
    .RuleFor(t => t.Id, f => f.IndexFaker)
    .RuleFor(t => t.Description, f => f.Lorem.Word());

var fakeBlogPostTags = new Faker<BlogPostTag>()
    .RuleFor(t => t.Tag, f => fakeTags.Generate());

This demonstrates that fakers can be chained, as all a faker is, is a way to generate data. So why not use fakers with other fakers to fake some data for your fake data? ;)

You can also create custom logic post-generation. As shown in the example, we are writing to the console on every generation of a blog post.

The final piece of the puzzle is to actually generate a blog post. With the new faker class finally configured, we can call generate:


var blogPost = testBlogPosts.Generate();

Console.WriteLine(JsonConvert.SerializeObject(blogPost, Formatting.Indented));

We can then serialise this object into JSON and write it to the console:


{
  "Id": 0,
  "Title": "Quo nulla eius expedita in velit omnis laboriosam adipisci ut.",
  "Content": "Quis hic suscipit. Omnis vero necessitatibus ea. Et qui ut temporibus consequatur est dolor nemo cum laboriosam. Sint accusamus cupiditate nisi et alias. Est aut voluptas.\n\nEsse provident quo soluta delectus cumque temporibus ut. Asperiores architecto atque iusto. Dicta voluptatem animi iusto dolorem a quia consectetur est. Nihil doloribus voluptatem omnis voluptas labore dolore.\n\nNihil quia quaerat explicabo delectus illum id necessitatibus. Sit occaecati quibusdam. Voluptates dicta repudiandae. Ab cum quas quia molestias tempora et non aliquam. Eum ut et sint maxime blanditiis voluptas aut optio eum.",
  "MetaDescription": "Modi et magni eos dicta impedit iure.\nIncidunt quidem asperiores.\nSunt aut quia sint.",
  "Keywords": "eveniet, laboriosam, rerum",
  "IsActive": true,
  "Created": "2017-07-12T07:45:06.6438607+01:00",
  "AuthorId": null,
  "Author": null,
  "Tags": [
    {
      "BlogPostId": 0,
      "BlogPost": null,
      "TagId": 0,
      "Tag": {
        "Id": 0,
        "Description": "reprehenderit",
        "BlogPosts": null
      }
    },
    {
      "BlogPostId": 0,
      "BlogPost": null,
      "TagId": 0,
      "Tag": {
        "Id": 1,
        "Description": "dicta",
        "BlogPosts": null
      }
    },
    {
      "BlogPostId": 0,
      "BlogPost": null,
      "TagId": 0,
      "Tag": {
        "Id": 2,
        "Description": "unde",
        "BlogPosts": null
      }
    }
  ]
}

With approximately 40 lines of code, I have created a blog post data generator. This is the true power of Bogus.

The generate method also accepts a number. You can create lists of blog posts at a time:


var blogPosts = testBlogPosts.Generate(10);

Or you can create lazily evaluated data with IEnumerable:


IEnumerable<BlogPost> blogPosts = testBlogPosts.GenerateLazy(10);

... other logic ...

foreach (var blogPost in blogPosts)
{
    ...
}

The limitations now with your seeding application. The hard part has been done for you, and now it should be a simple task of add this to entity framework's dbcontext, and saving it:


var blogPost = blogPostFaker.Generate();

using (var context = new ApplicationContext())
{
    context.Add(blogPost);

    var key = await context.SaveAsync();

    ...
}

Summary

Seeding is a necessary evil of our every day job. With Bogus, it becomes slightly easier. Whether you are wantings to populate an eCommerce site, a blog, or even something that has nothing to do with websites such as performance analysis.

Bogus is available as a .NET Standard 2.0 Nuget package. This means that you can use Bogus with virtually all flavours of .NET. You could use it with Xamarin to generate data on your mobile, or with desktop applications that require gigabytes of data. More importantly, you can create one seeding generator for your data, and share it throughout your entire application suite.

A fluent interface into a world of random data, Bogus is a mandatory tool for any programmer.

Thanks for reading, I hope this helps. The Bogus API is available on the readme here.

Share with a friend

Please share this blog post so others can learn from it as well.

Tweet about this on Twitter Share on Facebook Share on LinkedIn Share on Google+ Pin on Pinterest Share on Reddit Share on StumbleUpon

Recent Posts

Archives



© 2017 - Jack Histon - Blog