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.
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;
}
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;
}
}
Usage
We need a Contact with a ContactType
Contact contact = NorthWind.SingleContact();
A Category is needeed.
Categories category = NorthWind.SingleCategory();
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());
}
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);
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();
}
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.