Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to represent nullable values with bogus?

Tags:

c#

.net

bogus

There is a beautiful library that generates random/pseudo-random values for a DTO.

    var fruit = new[] { "apple", "banana", "orange", "strawberry", "kiwi" };

var orderIds = 0;
var testOrders = new Faker<Order>()
    //Ensure all properties have rules. By default, StrictMode is false
    //Set a global policy by using Faker.DefaultStrictMode
    .StrictMode(true)
    //OrderId is deterministic
    .RuleFor(o => o.OrderId, f => orderIds++)
    //Pick some fruit from a basket
    .RuleFor(o => o.Item, f => f.PickRandom(fruit))
    //A random quantity from 1 to 10
    .RuleFor(o => o.Quantity, f => f.Random.Number(1, 10));

To create a rule for an int is simple:

            .RuleForType(typeof(int), f => f.Random.Number(10, 1000))

How do we create rules for nullable primitive types?

For example if our model has nullable ints or nullable deimcals:

public class ObjectWithNullables
{

  public int? mynumber{get;set;}
  public decimal? mydec {get;set;}
}

We cannot construct like so:

.RuleForType(typeof(int?), f => f.Random.Number(10, 1000))

How do we represent nullables?

like image 841
Alex Gordon Avatar asked Dec 27 '17 18:12

Alex Gordon


2 Answers

Bogus has a .OrNull()/.OrDefault() extension methods in the Bogus.Extensions namespace.

To generate values that are randomly null try the following:

using Bogus.Extensions;

public class ObjectWithNullables
{
   public int? mynumber{get;set;}
   public decimal? mydec {get;set;}
}

var faker = new Faker<ObjectWithNullables>()
            // Generate null 20% of the time.
            .RuleFor(x=> x.mynumber, f=>f.Random.Number(10,1000).OrNull(f, .2f))
            // Generate null 70% of the time.
            .RuleFor(x=>x.mydec, f => f.Random.Decimal(8, 10).OrNull(f, .7f));

faker.Generate(10).Dump();

sample output

Hope that helps!

Thanks,
Brian

like image 57
Brian Chavez Avatar answered Nov 12 '22 00:11

Brian Chavez


A quick perusal seems to indicate you only need to use RuleForType when you are attempting to provide a single rule for all field/properties of a given type.

I think your issue with RuleForType is you did not pass in a lambda that returned the correct type. The type as the first parameter must match the return type of the lambda. Use

.RuleForType(typeof(int?), f => (int?)f.Random.Number(10, 1000))

If you need some possibility of null values, choose a percentage and return null occasionally:

.RuleForType(typeof(int?), f => (f.Random.Number(1,10) == 1 ? (int?)null : f.Random.Number(10, 1000)))
like image 27
NetMage Avatar answered Nov 12 '22 00:11

NetMage