Reputation: 4053
I would like to use AutoFixture (3.30.8) against my Entity Framework (6.1.3) data model. I have implemented the AutoFixture.AutoEF (0.3.5) package to help fix up the entities and avoid the circular references generated by the relationships.
However, my tables have several int columns which are represented by enums in code and I would like to be able to set the int values based on the enum values and have a proxy class for each of the enum values.
Here is a much simplified example of my schema:
public partial class MyContext : DbContext
{
public virtual DbSet<Parent> Parents { get; set; }
public virtual DbSet<Child> Children { get; set; }
}
public partial class Parent
{
public Parent()
{
this.Children = new HashSet<Child>();
}
public int Id { get; set; }
public string Name { get; set; }
public int Status { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public partial class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public int Type { get; set; }
public virtual Parent Parent { get; set; }
}
Here are my enums:
public enum Status
{
Active = 1,
Inactive = 2
}
public enum Type
{
Up = 1,
Down = 2,
Left = 3,
Right = 4
}
And here is how I am creating the proxies:
var fixture = new Fixture();
fixture.Customize(new EntityCustomization(new DbContextEntityTypesProvider(typeof(MyContext))));
var parents = fixture.CreateMany<Parent>();
This works in that I have a collection of 3 Parent
classes each with 3 Child
classes and the Id properties nicely match up. However, as expected, the Status
and Type
properties are random ints as generated by AutoFixture.
What I would like to have is 2 Parent
classes, one with Status
of 1
and one with Status
of 2
and for each of those to have 4 Child
classes, each one of those to have Type
of 1
, 2
, 3
and 4
.
Is this possible automatically using AutoFixture?
EDIT: To make it clearer what I am asking:
How can I automatically map an int property on my class to an enum so that I get one proxy class for each value of the mapped enum.
This will also need to work where a class has 2 or more mapped enums.
e.g. If Child
has Type
and Status
properties, I would expect 8 Children
per Parent
:
Status = 1, Type = 1
Status = 1, Type = 2
Status = 1, Type = 3
Status = 1, Type = 4
Status = 2, Type = 1
Status = 2, Type = 2
Status = 2, Type = 3
Status = 2, Type = 4
And to extrapolate further, if Parent
also had both Status
and Type
I would expect 8 Parent
proxy classes, each with 8 Child
proxy classes.
EDIT 2: Here is a sample of how my manually coded substitutes generator looks, if I've put both enums on both classes. By using AutoFixture I can automate everything except for the looping to generate every permutation of the Enums. That is what I am asking how to do.
public class Substitutes
{
private int parentIdSeed;
private int childIdSeed;
public Substitutes()
{
this.parentIdSeed = 0;
this.childIdSeed = 0;
this.Parents = new List<Parent>();
this.Children = new List<Child>();
this.GenerateParents();
}
private void GenerateParents()
{
foreach (Type type in Enum.GetValues(typeof(Type)))
{
foreach (Status status in Enum.GetValues(typeof(Status)))
{
this.parentIdSeed++;
var parent = new Parent { Id = this.parentIdSeed, Name = "Parent " + this.parentIdSeed, Status = (int)status, Type = (int)type };
this.GenerateChildren(parent);
this.Parents.Add(parent);
}
}
}
private void GenerateChildren(Parent parent)
{
foreach (Type type in Enum.GetValues(typeof(Type)))
{
foreach (Status status in Enum.GetValues(typeof(Status)))
{
this.childIdSeed++;
var child = new Child { Id = this.childIdSeed, Name = "Child " + this.childIdSeed, Status = (int)status, Type = (int)type, Parent = parent, ParentId = parent.Id };
parent.Children.Add(child);
this.Children.Add(child);
}
}
}
public List<Child> Children { get; set; }
public List<Parent> Parents { get; set; }
}
Upvotes: 2
Views: 801
Reputation: 233135
Yes, that is possible:
var parents = fixture.CreateMany<Parent>(2).ToList();
parents[1].Status = 1;
parents[1].Children = fixture.CreateMany<Child>(4).ToList();
parents[1].Children.ElementAt(1).Type = 1;
parents[1].Children.ElementAt(2).Type = 2;
parents[1].Children.ElementAt(3).Type = 3;
parents[1].Children.ElementAt(4).Type = 4;
parents[2].Status = 2;
parents[2].Children = fixture.CreateMany<Child>(4).ToList();
parents[2].Children.ElementAt(1).Type = 1;
parents[2].Children.ElementAt(2).Type = 2;
parents[2].Children.ElementAt(3).Type = 3;
parents[2].Children.ElementAt(4).Type = 4;
Upvotes: 1