Search code examples
c#.netfakerbogus

Generate a random number of Addresses each with a unique Type-value with Bogus Faker


Im using Bogus https://github.com/bchavez/Bogus/ for generating testdata.

I have a Person-object that has properties:

  • firstName,
  • lastName
  • addresses (list)

The Address-Object has properties:

  • streetAddress,
  • zipCode,
  • city
  • addressType,

AddressType has enums: { "work", "home", "SPAR" }

I would like to create a random number of addresses in person between 0 and number of values in AddressType which is 3 in this case. Each created address should have a unique AddressType-value.

What I have tried so far:

void Main()
{
    var fakePersons = new Faker<Person>(locale)
      .RuleFor(p => p.firstName, f => f.Name.FirstName(f.Person.Gender))
      .RuleFor(p => p.lastName, f => f.Name.LastName(f.Person.Gender))
      .RuleFor(p => p.addresses, (f, p) => GetAddresses(p).Generate(faker.Random.Number(3))) // from 0 to 3
}

private Faker<Address> GetAddresses(Person p)
{
    return new Faker<Address>(locale)
        .RuleFor(a => a.streetAddress, f => f.Address.StreetAddress())
        .RuleFor(a => a.city, f => f.Address.City())
        .RuleFor(a => a.zipCode, f => f.Address.ZipCode())
        .RuleFor(a => a.addressType, f => f.PickRandom<AddressType>())  // <===

}

This will create 0 to 3 addresses in person where each address can have any AddressType-value, so this will not rule out duplicates.

How can this be solved to save state of previously used AddressType-values so there will only be unique AddressType-values?

A side note. Instead of having to hard the number of AddressType-values (3) in the call to '''GetAddresses(p).Generate(faker.Random.Number(3))) // from 0 to 3'''

Is it possible to provide an expression that counts the number of AddressType enums?


Solution

  • I'm really no expert with Bogus, but it seems to me the simplest approach is to pick N address types, and then generate N addresses without types, and finally set the types for each generated address.

    private static readonly AddressType[] AllAddressTypes = Enum.GetValues(typeof(AddressType))
                                                           .Cast<AddressType>()
                                                           .ToArray();
    
    private ICollection<Address> GetRandomAddresses(Faker faker, Person p)
    {
        // Select random number of addresses,
        // and the same number of random address types
        var num = faker.Random.Number(AllAddressTypes.Length);
        var types = faker.PickRandom(AllAddressTypes, num).ToArray();
    
    
        // Build the addresses, without type
        var addresses = GetAddresses(p).Generate(num);  
    
        // Set the address type for each new address
        for(var i = 0; i < addresses.Count; ++i) {
            addresses[i].addressType = types[i];
        }   
        return addresses;
    }