Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bogus faked data: Conditional and random in the same field, possibly leaving a null faked data

Tags:

c#

.net

faker

bogus

In using .net Bogus github repository for filling up a database, I would like to both fill a field randomly with something like:

{ "Mother", "Sister", "Brother", "Father", "Uncle","Niece","Nephew","Cousin"}

But also randomly leave occasional nulls too?

I have tried chaining them together but it doesn't seem like there is a syntax that the compiler likes.

                .RuleFor(u => u.Gender, f => f.PickRandom<Gender>().ToString())
                .RuleFor(u => u.BirthDate, f => f.Date.PastOffset(60,
                    DateTime.Now.AddYears(-18)).Date.ToShortDateString())
                .RuleFor(u => u.FirstName, (f, u) => f.Name.FirstName(ReturnGenderType(u.Gender)))
                .RuleFor(u => u.MiddleName, (f, u) => f.Name.FirstName(ReturnGenderType(u.Gender)))
                .RuleFor(u => u.LastName, (f, u) => f.Name.LastName(ReturnGenderType(u.Gender)))
                .RuleFor(u => u.Salutation, (f, u) => f.Name.Prefix(ReturnGenderType(u.Gender)))

 private static Bogus.DataSets.Name.Gender ReturnGenderType(string genderString)
        {
            if (genderString == "Male")
            {
                return Bogus.DataSets.Name.Gender.Male;
            }
            else
            {
                return Bogus.DataSets.Name.Gender.Female;
            }
        }

In this example it looks like it might have to be an extension as the Gender type feeds back later into the sane but random names later.

like image 202
SuperDave Avatar asked Jan 26 '23 09:01

SuperDave


1 Answers

If you want Bogus to generate "sometimes null" values in rules, you can use the convenient .OrNull() extension method. The following example shows to generate nullable values with a 20% probability:

void Main()
{
   var userFaker = new Faker<User>()
            .RuleFor( u => u.FirstName, f => f.Name.FirstName())
            .RuleFor( u => u.LastName, f => f.Name.LastName().OrNull(f, .2f) );

   userFaker.Generate(10).Dump();
}

public class User{
   public string FirstName{get;set;}
   public string LastName{get;set;}
}

You can also remove the ReturnGenderType helper method and use the f => f.Person property instead. Summing it all up, here's how your code cleans up:

void Main()
{
   var userFaker = new Faker<User>()
    .RuleFor(u => u.Gender,     f => f.Person.Gender.ToString())
    .RuleFor(u => u.BirthDate,  f => f.Date.PastOffset(60, DateTime.Now.AddYears(-18)).Date.ToShortDateString())
    .RuleFor(u => u.FirstName,  f => f.Person.FirstName)
    .RuleFor(u => u.MiddleName, f => f.Name.FirstName(f.Person.Gender).OrNull(f, .2f))
    .RuleFor(u => u.LastName,   f => f.Person.LastName)
    .RuleFor(u => u.Salutation, f => f.Name.Prefix(f.Person.Gender));

   userFaker.Generate(10).Dump();
}

public class User
{
   public string Gender { get; set; }
   public string BirthDate { get; set; }
   public string FirstName { get; set; }
   public string MiddleName { get; set; }
   public string LastName { get; set; }
   public string Salutation { get; set; }
}

BTW, the Salutation generated by f.Name.Prefix(Gender) is sometimes not right because gender prefixes are not separated in the en locale. If this is a concern, you can extend Bogus a tiny bit more with an extension method that fixes your locale:

public static class MyExtensionsForBogus{
   public static string Prefix2(this Bogus.DataSets.Name name, Gender gender)
   {
      if (gender == Gender.Male)
      {
         return name.Random.ArrayElement(new[] { "Mr.", "Dr." });
      }
      return name.Random.ArrayElement(new[]{"Miss", "Ms.", "Mrs."});
   }
}

Then, the new Salutation rule becomes:

    .RuleFor(u => u.Salutation, f => f.Name.Prefix2(f.Person.Gender));

And now ya got some nice looking data there:

Hope that helps! =)

like image 52
Brian Chavez Avatar answered Feb 01 '23 06:02

Brian Chavez