I have the following type hierarchy:
public abstract class ResourceId
{
}
public class CarId : ResourceId
{
}
public class PlaneId: ResourceId
{
}
public interface IResource
{
ResourceId Id { get; set; }
}
public class Plane : IResource
{
public ResourceId Id { get; set; }
}
public class Car : IResource
{
public ResourceId Id { get; set; }
}
I want AutoFixture to create the 'right' type of ResourceId when it tries to create a Plane or Car.
I tried using:
_fixture.Customize<Plane>(composer =>
composer.With(h => h.Id, _fixture.Create<PlaneId>()));
But of course that creates the same ID for each instance. I want each to have a unique ID.
What is the best approach for this?
There's a way to do what you ask for but it requires a lesser-known customization API: the Register
method.
The purpose of Register
is to allow the user to specify a factory function for a specific type. AutoFixture will then delegate the creation of objects of that type to the function.
One distinctive feature of Register
is that it's able to provide anonymous objects to pass as arguments to the factory function whenever they're needed. It does so through a number of overloads. Here are a few examples:
Register<T>(Func<T> factory)
doesn't provide any arguments to the factoryRegister<T1, T>(Func<T1, T> factory)
provides one argument of type T1
to create objects of type T
Register<T1, T2, T>(Func<T1, T2, T> factory)
provides two arguments of type T1
and T2
to create objects of type T
Now, we can use this feature to customize the way objects of type Car
and Plane
are created by assigning anonymous instances of CarId
and PlanId
to their Id
properties:
[Fact]
public void Test()
{
var fixture = new Fixture();
fixture.Register<CarId, Car>(id =>
{
var resource = new Car { Id = id };
return resource;
});
fixture.Register<PlaneId, Plane>(id =>
{
var resource = new Plane { Id = id };
return resource;
});
Assert.NotSame(fixture.Create<Car>().Id, fixture.Create<Car>().Id);
Assert.NotSame(fixture.Create<Plane>().Id, fixture.Create<Plane>().Id);
}
This test passes because the CarId
and PlanId
objects that are passed to the factory functions are created by AutoFixture, thus being different every time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With