Thanasi Poulos
Thanasi Poulos

Reputation: 278

Autofixture - base property in new list on property from a previously constructed one

I think I'm missing something, but what I'm trying to do is this:

I have two database entities represented in my C# code. One is a child of the other, therefore the child contains a field which should reference the parent's ID.

The parent class is the following

public class Product
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public decimal Price { get; set; }

    public decimal DeliveryPrice { get; set; }
}

The child class is the following:

public class ProductOption
{
    public Guid Id { get; set; }

    public Guid ProductId { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }
}

I have created a list of random "parents" as such:

var products = fixture.CreateMany<Product>(5).ToList();

What I wanted to do was then create 10 child objects, and randomly give them a ProductId from the list of products created by AutoFixture. So I tried this:

var rand = new Random();
var options = fixture.Build<ProductOption>()
    .With(option => option.ProductId, products[rand.Next(0, 5)].Id)
    .CreateMany(10)
    .ToList();

It almost worked, but what I found was that all the ProductIds were the same one, so it obviously only ever hit rand.Next once.

Is what I'm doing even possible/advisable?

Upvotes: 1

Views: 1166

Answers (1)

Fabio
Fabio

Reputation: 32445

When I provide value for the property, I would expect all instances build with same builder/fixture will have provided value.
So what you noticed is desired behaviour.

Instead of already generated value you can provide a "factory" which will generate value for the property during instance creation.
Latest Autofixture version introduced overload for .With method which accepts a function as parameter.

var rand = new Random();
Func<Guid> pickProductId = () => products[rand.Next(0, 5)].Id;

var options = 
    fixture.Build<ProductOption>()
           .With(option => option.ProductId, pickProductId)
           .CreateMany(10)
           .ToList();

// Prove
options.Select(o => o.ProductId).ToHashSet().Should().HaveCountGreaterThan(1); // Pass Ok

Upvotes: 3

Related Questions