Shevek
Shevek

Reputation: 4053

AutoFixture with Entity Framework - mapping int to enum

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

Answers (1)

Mark Seemann
Mark Seemann

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

Related Questions