I have the following types:
public enum Status
{
Online,
Offline
}
public class User
{
private readonly Status _status;
public User(Status status) { _status = status; }
public Status Status {get {return _status; }}
public string Name {get;set;}
}
Now, when executing fixture.CreateMany<User>
I want AutoFixture to return two Users
, one per status. All other properties - like Name
- should be filled with anonymous data.
Question:
How to configure AutoFixture to do this?
I tried the following this:
Register collection that news up the User
object:
fixture.Register(
() => Enum.GetValues(typeof(Status)).Cast<Status>().Select(s =>
new User(s)));
The problem with this approach is that AutoFixture doesn't fill the other properties like Name
Customize User
to use a factory and register a collection that uses fixture.Create
:
f.Customize<User>(c => c.FromFactory((Status s) => new User(s)));
f.Register(() =>
Enum.GetValues(typeof(Status))
.Cast<Status>()
.Select(s => (User)f.Create(new SeededRequest(typeof(User), s),
new SpecimenContext(f))));
That didn't work either. The seed isn't being used.
You could do this:
var users = new Fixture().Create<Generator<User>>();
var onlineUser = users.Where(u => u.Status == Status.Online).First();
var offlineUser = users.Where(u => u.Status == Status.Offline).First();
If you're using AutoFixture.Xunit, the declarative equivalent is:
[Theory, AutoData]
public void CreateOneOfEachDeclaratively(Generator<User> users)
{
var onlineUser = users.Where(u => u.Status == Status.Online).First();
var offlineUser = users.Where(u => u.Status == Status.Offline).First();
// Use onlineUser and offlineUser here...
}
You may declare and use a customization, e.g. StatusGenerator
:
var fixture = new Fixture();
fixture.RepeatCount = 2;
fixture.Customizations.Add(new StatusGenerator());
var result = fixture.CreateMany<User>();
A hypothetical implementation of the StatusGenerator
could be the following:
internal class StatusGenerator : ISpecimenBuilder
{
private readonly Status[] values;
private int i;
internal StatusGenerator()
{
this.values =
Enum.GetValues(typeof(Status)).Cast<Status>().ToArray();
}
public object Create(object request, ISpecimenContext context)
{
var pi = request as ParameterInfo;
if (pi == null || !pi.ParameterType.IsEnum)
return new NoSpecimen(request);
return this.values[i == this.values.Length - 1 ? i = 0 : ++i];
}
}
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