Bogus custom Dataset

Karen Payne - Jan 6 - - Dev Community

Introduction

Bogus NuGet package is fake data generator which can be helpful for populating tables in a database and testing purposes. If a database is not used and Bogus populates list of data each time an application runs, the data is random, never the same. Also, the random data generated by Bogus may not meet a developer’s requirements.

For this reason, Bogus can be extended with a DataSet. Normal use of a DataSet is to set the locale for data generation but in this article learn how to use a Bogus DataSet to use realistic data.

The model will be three tables from a modified Microsoft NorthWind database (script is included in source code), Category, Contact and ContactType.

demonstration screen shot

Steps to create a custom DataSet

Create the models which match tables in NorthWind database.

public class Categories
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public string Description { get; set; }
    public byte[] Photo { get; set; }
    public Bitmap Picture { get; set; }
}

public class Contact
{
    public int ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int ContactTypeIdentifier { get; set; }
    public ContactType ContactType { get; set; } = new();
    public override string ToString() => $"{FirstName} {LastName}";

    public Contact(int id)
    {
        ContactId = id;
    }

    public Contact()
    {

    }

}

public class ContactType
{
    public int ContactTypeIdentifier { get; set; }
    public string ContactTitle { get; set; }
    public override string ToString() => ContactTitle;

}
Enter fullscreen mode Exit fullscreen mode

Next, read data from the database into json strings. Recommend using Microsoft Visual Studio Code with SQL Server (mssql) extension (free) which a SELECT statement can be exported to a json file. Once exported, paste the json into a method. In this case view BogusNorthWindLibrary.Classes.JsonStatements methods which stored json in raw string literals.

Next create a class which inherits Bogus DataSet as shown below.

Each method reads data from the json discussed prior.

Note
Do not overthink performance here.

public class NorthWind : DataSet
{

    private static Categories RandomCategory 
        => System.Random.Shared.GetItems(categories()!.ToArray(), 1)[0];


    public static Categories SingleCategory() 
        => RandomCategory;

    private static List<Categories>? categories()
    {
        List<Categories>? list = JsonSerializer
            .Deserialize<List<Categories>>(JsonStatements.CategoriesData);

        foreach (var cat in list!)
        {
            cat.Picture = cat.Photo.ByteToImage();
        }

        return list;
    }

    public static ContactType GetContactType(int id) 
        => JsonSerializer.Deserialize<List<ContactType>>(JsonStatements.ContactTypeData)!
            .FirstOrDefault(x => x.ContactTypeIdentifier == id)!;

    public static Contact SingleContact()
    {
        var contact = System.Random.Shared.GetItems(JsonSerializer
            .Deserialize<List<Contact>>(JsonStatements.ContactData)!.ToArray(), 1)[0];
        var contactType = GetContactType(contact.ContactTypeIdentifier);
        contact.ContactType = contactType;

        return contact;
    }
}
Enter fullscreen mode Exit fullscreen mode

Usage

We need a Contact with a ContactType

Contact contact = NorthWind.SingleContact();
Enter fullscreen mode Exit fullscreen mode

A Category is needeed.

Categories category = NorthWind.SingleCategory();
Enter fullscreen mode Exit fullscreen mode

Integration into a create Faker

First thing required is an extension method

public static class BogusExtensions
{
    /// <summary>
    /// Entry point for faker RuleFor
    /// </summary>
    public static NorthWind NorthWind(this Faker faker) 
        => ContextHelper.GetOrSet(faker, () => new NorthWind());
}
Enter fullscreen mode Exit fullscreen mode

Setup static data and note the contact titles could be obtained from extraction from the json data used prior.

private static string[] contactTitles { get; } = [
    "Accounting Manager",
    "Assistant Sales Agent",
    "Assistant Sales Representative",
    "Marketing Assistant",
    "Marketing Manager",
    "Order Administrator",
    "Owner",
    "Owner/Marketing Assistant",
    "Sales Agent",
    "Sales Associate",
    "Sales Manager",
    "Sales Representative",
    "Vice President, Sales"
];

public string ContactTypeNames()
    => Random.ArrayElement(contactTitles);
Enter fullscreen mode Exit fullscreen mode

Now let's create a ContactType with a known title but with random first and last name.

public ContactType ContactTypes()
{
    var data = new Faker<ContactType>()
        .RuleFor(p => p.ContactTypeIdentifier, p => p.Random.Int(1, 10))
        .RuleFor(p => p.ContactTitle, f => f.NorthWind().ContactTypeNames());

    return data.Generate();

}
Enter fullscreen mode Exit fullscreen mode

Summary

Although NorthWind database was the target, once the reader has studied and understands the code provided this will work for any data. The main example to focus on is Contact/ContactType.

Source code

Clone the following GitHub repository

Requires

Microsoft Visual Studio 2022 with NET8 Framework installed.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .