When it comes to testing in C#, creating fake or mock data is a common requirement. Two popular libraries for achieving this are Bogus and AutoFixture. In this blog post, we'll explore both libraries, compare their features, and provide code examples to showcase their capabilities.
Before I do that here is a quick view on the statistics of both libraries.
Comparison 8/10/2023 | Bogus | AutoFixture |
---|---|---|
Source Link | Github | Github |
NuGet Link | Nuget | Nuget |
NuGet Downloads (Total) | 55.8M | 116.6M |
NuGet Downloads (Per Day) | 18.3K | 25.1K |
Github Stars | 7.7k | 3.1k |
Github Watchers | 125 | 94 |
Github Forks | 450 | 339 |
It must be noted that numbers alone don't give you the full picture of a library and if one is better than the other. In most case you'll find that each library handles certain use cases better than others. So if you're looking to use one of these nuget libraries then it would depend on your use case given you understand what each library can offer.
That said with the numbers alone it's safe to say these are two very popular libraries. I find the type of statistics above useful when I want to use a library, but I am not sure if it's ok to use based off the following:
In both examples I used the following classes to generate fake data for. You can find the code from all the examples on this github repo.
public record Address(string Line1, string Line2, string Town, string PostCode, string Country);
public record Person(string FirstName, string LastName, string Email, Address Address);
Bogus allows you to create realistic-looking test data with minimal effort by using predefined fake data generators.
Highlights:
using Bogus;
using System.Runtime.Serialization;
using System.Text.Json;
using Xunit.Abstractions;
namespace FakeData.Examples.Tests
{
public class BogusTests
{
private readonly ITestOutputHelper outputHelper;
public BogusTests(ITestOutputHelper outputHelper)
{
this.outputHelper = outputHelper;
}
[Fact]
public void Person()
{
// Create a Faker instance for generating fake data
var faker = new FakeDataGenerator();
// Generate a fake person
var fakePerson = faker.Person.Generate();
outputHelper.WriteLine(JsonSerializer.Serialize(fakePerson));
}
}
public class FakeDataGenerator
{
public Faker<Person> Person;
public Faker<Address> Address;
public FakeDataGenerator()
{
Address = new Faker<Address>()
.WithRecord()
.StrictMode(true)
.RuleFor(o => o.Line1, f => f.Address.StreetAddress())
.RuleFor(o => o.Line2, f => f.Address.SecondaryAddress())
.RuleFor(o => o.Town, f => f.Address.City())
.RuleFor(o => o.PostCode, f => f.Address.ZipCode())
.RuleFor(o => o.Country, f => f.Address.Country());
Person = new Faker<Person>()
.WithRecord()
.StrictMode(true)
.RuleFor(o => o.FirstName, f => f.Person.FirstName)
.RuleFor(o => o.LastName, f => f.Person.LastName)
.RuleFor(o => o.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName))
.RuleFor(o => o.Address, Address.Generate());
}
}
public static class ExtensionsForBogus
{
public static Faker<T> WithRecord<T>(this Faker<T> faker) where T : class
{
faker.CustomInstantiator(_ => FormatterServices.GetUninitializedObject(typeof(T)) as T);
return faker;
}
}
}
Example output:
{
"FirstName": "Carole",
"LastName": "Fay",
"Email": "Carole.Fay@hotmail.com",
"Address": {
"Line1": "678 Geovany Forest",
"Line2": "Suite 413",
"Town": "Jeremychester",
"PostCode": "20819",
"Country": "Venezuela"
}
}
AutoFixture takes a different approach by focusing on automating the process of creating test data without much manual configuration.
Highlights:
using AutoFixture;
using System.Text.Json;
using Xunit.Abstractions;
namespace FakeData.Examples.Tests
{
public class AutoFixtureTests
{
private readonly ITestOutputHelper outputHelper;
public AutoFixtureTests(ITestOutputHelper outputHelper)
{
this.outputHelper = outputHelper;
}
[Fact]
public void Person()
{
// Create a Fixture instance for generating auto-mocked data
var fixture = new Fixture();
// Generate a person with auto-mocked data
var person = fixture.Build<Person>()
.With(x => x.Email, "test@email.com")
.Create();
outputHelper.WriteLine(JsonSerializer.Serialize(person));
}
}
}
Example output:
{
"FirstName": "FirstNamef1b2b680-0a79-4015-96bf-8b36a39ec79d",
"LastName": "LastName2af92601-cc8e-4bf2-b458-21abf995fb0a",
"Email": "test@email.com",
"Address": {
"Line1": "Line16a0323fa-4db8-4e70-adc3-8091e5408618",
"Line2": "Line2527e5086-140c-4201-b361-2ac2952acf4d",
"Town": "Towndfd93b2f-1728-47e8-86a0-d0bb55a1b1ae",
"PostCode": "PostCodeadf7d835-9249-42f0-b82a-0b80002084f5",
"Country": "Countrye942137a-8641-4f1c-a362-b2761903fb3e"
}
}
Choosing between Bogus and AutoFixture depends on your specific needs and preferences. Bogus excels in providing a rich set of data generators with explicit customization, while AutoFixture offers a more automated, convention-based approach for quickly generating test data.
Ultimately, the choice between these two libraries comes down to the level of control and customization you desire in your test data generation process. Each has its strengths, and the best fit depends on the nature of your testing scenarios.