RoboBogus

A C# library complementing the Bogus generator by adding auto creation and population capabilities.


Keywords
License
MIT
Install
Install-Package RoboBogus -Version 0.1.0

Documentation

RoboBogus

Build status NuGet Status NuGet Status NuGet Status NuGet Status

This is a hard fork of the awesome AutoBogus by Nick Dodd

A C# library complementing the Bogus generator by adding auto creation and population capabilities.

The following packages are available for download from NuGet:

Configuration

There are several levels of configuration available.

  • Global > this is scoped as the default configuration across all generate requests.
  • Faker > this is scoped as the configuration applied to all generate requests for an AutoFaker instance.
  • Generate > this is scoped as the configuration for a specific generate request.

The above levels are hierarchical and in the order listed. Therefore, if a setting is not set for a Generate configuration, then the Faker value is used and then the Global.

Builder

A configuration is defined via a builder action that invokes the relevant setup method.

// Configure globally
AutoFaker.Configure(builder =>
{
  builder
    .WithLocale()         	// Configures the locale to use
    .WithRepeatCount()    	// Configures the number of items in a collection
    .WithDataTableRowCount()	// Configures the number of data table rows to generate
    .WithRecursiveDepth() 	// Configures how deep nested types should recurse
    .WithTreeDepth()		// Configures the tree depth of an object graph
    .WithBinder()         	// Configures the binder to use
    .WithFakerHub()       	// Configures a Bogus.Faker instance to be used - instead of a default instance
    .WithSkip()           	// Configures members to be skipped for a type
    .WithOverride();      	// Configures the generator overrides to use - can be called multiple times
});

// Configure a faker
var faker = AutoFaker.Create(builder => ...);

// Configure a generate request
faker.Generate<TType>(builder => ...);
faker.Generate<TType, TFaker>(builder => ...);

AutoFaker.Generate<TType>(builder => ...);
AutoFaker.Generate<TType, TFaker>(builder => ...);

// Configure an AutoFaker<T> 
var personFaker = new AutoFaker<Person>()
  .Configure(builder => ...)
  .RuleFor(fake => fake.Id, fake => fake.Random.Int())
  .Generate();

The Generate<TType, TFaker>() methods also include WithArgs() so constructor arguments can be defined for the TFaker instance.

Usage

AutoFaker

The non-generic AutoFaker class provides convenience methods to generate type instances.

It can be used statically or as a configured instance. The static methods provide a means of quickly generating types on-the-fly and the instance can be reused across multiple generate requests.

Static

AutoFaker.Generate<int>();
AutoFaker.Generate<Person>();

Instance

var faker = AutoFaker.Create();

faker.Generate<int>();
faker.Generate<Person>();

AutoFaker<T>

The AutoFaker<T> class is a Bogus wrapper that adds auto generation for member values. In turn, it means all the goodness of Bogus is automatically available (e.g. rule sets).

var personFaker = new AutoFaker<Person>()
  .RuleFor(fake => fake.Id, fake => fake.Random.Int())
  .RuleSet("empty", rules =>
  {
    rules.RuleFor(fake => fake.Id, () => 0);
  });

// Use explicit conversion or call Generate()
var person1 = (Person)personFaker;
var person2 = personFaker.Generate();

person1.Dump();
person2.Dump();

// An existing instance can also be populated
var person3 = new Person();

personFaker.Populate(person3);
person3.Dump();

When the AutoFaker<T> class is inherited, either instantiate an instance or use the AutoFaker class to auto instantiate and invoke a Generate() method.

public class PersonFaker : AutoFaker<Person>
{
  public PersonFaker(int id)
  {
    RuleFor(fake => fake.Id, () => id)
  }
}

var id = AutoFaker.Generate<int>();

// Create an instance and call Generate()
var personFaker = new PersonFaker(id);
var person1 = personFaker.Generate();

person1.Dump();

// Create a Person instance using AutoFaker.Generate()
// If the AutoFaker<T> class needs constructor arguments, they can be passed using WithArgs()
var person2 = AutoFaker.Generate<Person, PersonFaker>(builder => builder.WithArgs(id));

person2.Dump();

Note that, should a rule set be used to generate a type, then only members not defined in the rule set are auto generated. In the examples above, the Id member will not be generated, but will instead use the RuleFor value.

Binders

A default IAutoBinder implementation is included, but it will not generate interfaces or abstract classes. For this, the following packages are available:

Skipping

The generating of values can be skipped based on either a type or the member path of a type.

AutoFaker.Configure(builder =>
{
  // Types
  builder
    .WithSkip<Address>()                      // Define a generic type
    .WithSkip(typeof(Country));               // Define a type

  // Type members
  builder
    .WithSkip<Person>(person => person.Name); // Define using an expression for public members
    .WithSkip<Person>("Age");                 // Define using a string for protected, internal, etc. members
    .WithSkip(typeof(Person), "Gender");      // Define using a string for protected, internal, etc. members
});

Overrides

In some cases, custom rules are needed to generate a type and for this, RoboBogus provides generator overrides. By implementing a class that inherits AutoGeneratorOverride and registering it via a configuration, these custom rules can be invoked as part of a generate request.

public class PersonOverride : AutoGeneratorOverride
{
  public override bool CanOverride(AutoGenerateContext context)
  {
    return context.GenerateType == typeof(Person);
  }

  public override void Generate(AutoGenerateOverrideContext context)
  {
    // Apply an email value to the person
    var person = context.Instance as Person;
    person.Email = context.Faker.Internet.Email();
  }
}

// Register the override
AutoFaker.Configure(builder => builder.WithOverride(new PersonOverride()));

Note that a virtual Preinitialize property is available to control whether an initial value should be generated. This defaults to true.

Behaviors

The following underlying behaviors are in place:

  • Interface and abstract class types are not auto generated - they will result in null values. A custom binder would be needed, like one of the packages listed above.
  • Rescursive types - a nested member with the same parent type - will be generated to 2 levels by default to avoid a StackOverflowException - Person.Parent -> Person.Parent -> null
  • Read only properties - if a property is read only but can be resolved as an ICollection<> or IDictionary<,>, then it will be populated via the Add() method.

Conventions

The RoboBogus.Conventions package provides conventions for generating values, currently based on generation type and name. As an example, a property named Email and of type string will be assigned a value using the Faker.Internet.Email() generator.

To include the conventions, apply the following configuration at the required level:

AutoFaker.Configure(builder =>
{
  builder.WithConventions();
});

Each convention generator maps to a Bogus generator method and can be configured individually.

AutoFaker.Configure(builder =>
{
  builder.WithConventions(config =>
  {
    config.FirstName.Enabled = false;      // Disables the FirstName generator
    config.LastName.AlwaysGenerate = true; // Overrides any LastName values previously generated
    config.Email.Aliases("AnotherEmail");  // Generates an email value for members named AnotherEmail
  });
});

Templating

The RoboBogus.Templating package allows value generation rules to be defined using a text based templating notation.

This can be used by using the GenerateWithTemplate() extension method.

class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Status { get; set; }
}

snippet source | anchor

var faker = new AutoFaker<Person>(binder);
faker.Configure(_ => _.WithConsistentSeed());
var persons = faker.GenerateWithTemplate(@"
Id | FirstName | LastName
1  | John      | Smith
2  | Jane      | Jones
3  | Bob       | Clark
");

snippet source | anchor

Results in:

[
  {
    Id: Id_1,
    FirstName: John,
    LastName: Smith,
    Status: collaborative
  },
  {
    Id: Id_2,
    FirstName: Jane,
    LastName: Jones,
    Status: withdrawal
  },
  {
    Id: Id_3,
    FirstName: Bob,
    LastName: Clark,
    Status: extend
  }
]

snippet source | anchor

Icon

Robot designed by Kemesh Maharjan from The Noun Project