Lifelike Test Data Generation with Bogus

Bogus is a lovely library from Brian Chavez to use in automated tests to automatically generate test data of different kinds.

As an example suppose the following class is involved in a unit test:

public class Review
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public int Rating { get; set; }
    public DateTimeOffset Created { get; set; }

    public override string ToString()
        return $"{Id} '{Title}'";

In a test, a Review instance may need properties populating with values. This could be done manually, for example to check the ToString() implementation:

public void BeRepresentedAsAString()
    var sut = new Review
        Id = 42,
        Title = "blah blah"

    Assert.Equal("42 'blah blah'", sut.ToString());

Notice in the preceding test, the actual values and title don’t really matter, only the fact that they’re joined as part of the ToString() call. In this example the values for Id and Title could be considered anonymous variable / values in that we don’t really care about them.

The following test uses the Bogus NuGet package and uses its non-fluent facade syntax:

public void BeRepresentedAsAString_BogusFacadeSyntax()
    var faker = new Faker("en"); // default en

    var sut = new Review
        Id = faker.Random.Number(),
        Title = faker.Random.String()

    Assert.Equal($"{sut.Id} '{sut.Title}'", sut.ToString());

Bogus also has a powerful fluent syntax to define what a test object will look like. To use the fluent version, a Faker<T> instance is created where T is the test object to be configured and created, for example:

public void BeRepresentedAsAString_BogusFluentSyntax()
    var reviewFaker = new Faker<Review>()
        .RuleFor(x => x.Id, f => f.Random.Number(1, 10))
        .RuleFor(x => x.Title, f => f.Lorem.Sentence());

    var sut = reviewFaker.Generate(); 

    Assert.Equal($"{sut.Id} '{sut.Title}'", sut.ToString());

The first argument to the RuleFor() methods allows the property of the Review object to be selected and the second argument specifies how the property value should be generated. There is a huge range of test data types supported. In the preceding code the Random API is used as well as the Lorem API.

Some examples of the types of auto generated data include:

  • Addresses: ZipCode, City, Country, Latitude, etc.
  • Commerce: Department name, ProductName, ProductAdjective, Price, etc.
  • Company: CompanyName, CatchPhrase, Bs, etc.
  • Date: Past, Soon, Between, etc.
  • Finance: Account number, TransactionType, Currency, CreditCardNumber, etc.
  • Image URL: Random image, Animals image, Nature image, etc.
  • Internet: Email, DomainName, Ipv6, Password, etc.
  • Lorem: single word, Words, Sentence, Paragraphs, etc.
  • Name: FirstName, LastName, etc.
  • Rant: Random user review, etc.
  • System: FileName, MimeType, FileExt, etc.

Some of the random generated values are quite entertaining, for example Rant.Review() may produce "My co-worker Fate has one of these. He says it looks tall."; Company.Bs() may produce "transition cross-media users", and Company.CatchPhrase() may produce "Face to face object-oriented focus group".

Bogus configuration is quite powerful and allows fairly complex setup as the following code demonstrates:

public void CalculateAverageRatingWhenMultipleReviews()
    int rating = 0;

    var reviewFaker = new Faker<Review>()
        .RuleFor(x => x.Id, f => f.Random.Number(1, 10))
        .RuleFor(x => x.Rating, f => rating++);

    var productFaker = new Faker<Product>()
        .RuleFor(x => x.PricePerUnit, f => f.Finance.Amount())
        .RuleFor(x => x.Description, f => f.WaffleText(3))
        .FinishWith((f, x) =>
                reviewFaker.Generate(3).ForEach(r => x.Reviews.Add(r));

    var sut = productFaker.Generate();

    Assert.Equal(1, sut.AverageRating); // (0 + 1 + 2) / 3

The WaffleText() API is provided by one of the extensions to Bogus (WaffleGenerator.Bogus) that produces inane looking waffle text such as the following:

The Quality Of Hypothetical Aesthetic

"The parallel personal hardware cannot explain all the problems in maximizing the efficacy of any fundamental dichotomies of the logical psychic principle. Generally the requirements of unequivocal reciprocal individuality is strictly significant. On the other hand the characteristic organizational change reinforces the weaknesses in the evolution of metaphysical terminology over a given time limit. The objective of the explicit heuristic discordance is to delineate the truly global on-going flexibility or the preliminary qualification limit. A priority should be established based on a combination of functional baseline and inevitability of amelioration The Quality Of Hypothetical Aesthetic"

 - Michael Stringer in The Journal of the Proactive Directive Dichotomy (20174U)

structure plan.

To make the main points more explicit, it is fair to say that;
  * the value of the optical continuous reconstruction is reciprocated by what should be termed the sanctioned major issue.
  * The core drivers poses problems and challenges for both the heuristic non-referent spirituality and any discrete or Philosophical configuration mode.
  * an anticipation of the effects of any interpersonal fragmentation reinforces the weaknesses in the explicit deterministic service. This may be due to a lack of a doctrine of the interpersonal quality..
  * any significant enhancements in the strategic plan probably expresses the strategic personal theme. This trend may dissipate due to the personal milieu.

 firm assumptions about ideal major monologism evinces the universe of attitude.

The Flexible Implicit Aspiration.

Within current constraints on manpower resources, any consideration of the lessons learnt can fully utilize what should be termed the two-phase multi-media program.

For example, the assertion of the importance of the integration of doctrine of the prime remediation with strategic initiatives cannot be shown to be relevant. This is in contrast to the strategic fit.

To learn more about Bogus head over to the documentation.

Add comment