I'm using Bogus to generate test data but I have some fields that depend on parts of another object (that I want to be chosen randomly for each generation) but that have to be consistent with each other.
That's probably not the best explanation so hopefully this example explains it better.
I have an Order
which includes the ID and currency from a Customer
.
public class Customer
{
public Guid Id { get; set; }
public string Currency { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public Guid CustomerId { get; set; } // The ID of a customer
public string Currency { get; set; } // The currency for the customer identified by CustomerId
public decimal Amount { get; set; }
}
I can generate some customers using:
var customerFaker =
new Faker<Customer>()
.StrictMode(true)
.RuleFor("Id", f => f.Random.Guid())
.RuleFor("Id", f => f.Finance.Currency());
var customers = customerFaker.Generate(10);
But I get stuck when it comes to "sharing" the customer that's been chosen between rules in the order generator:
var orderFaker =
new Faker<Order>()
.StrictMode(true)
.RuleFor("Id", f => f.Random.Guid())
.RuleFor("Amount", f => f.Finance.Amount())
.RuleFor("CustomerId", f => f.PickRandom(customers).Id)
//How do I share the Customer that's been chosen to use it in the rule below?
.RuleFor("Currency", f => f.PickRandom(customers).Currency);
I've come up with a few less-than-ideal ways of doing it (like instantiating a new Faker each time and passing in a random customer) but I'm working with quite complicated objects and dependencies so I'd like to avoid that if possible.
My current thinking is that the best way might be to extend the Order
class to be able to store the Customer
and then cast it back to being an order later. I'd like to avoid this if possible given the number of models I'll need to do this for.
public class OrderWithCustomer : Order
{
public Customer Customer { get; set; }
}
var orderWithCustomerFaker =
new Faker<OrderWithCustomer>()
.StrictMode(true)
.RuleFor("Id", f => f.Random.Guid())
.RuleFor("Amount", f => f.Finance.Amount())
.RuleFor("Customer", f => f.PickRandom(customers))
.RuleFor("CustomerId", (f, o) => o.Customer.Id)
.RuleFor("Currency", (f, o) => o.Customer.Currency);
var orders =
orderWithCustomerFaker
.Generate(10)
.Select(withCustomer => (Order)withCustomer);