6

I'm trying to generate specific values for a class with AutoFixture but the Builder is given an abstract class. As such, the builder can't see the properties for either concrete types ... and therefore cannot/doesn't know when/how to create them.

e.g.

public abstract class BaseClass
{
    // Common properties.
    public string Id { get; set }
    public Baa Baa { get; set; }
}

public class ConcreteA : BaseClass
{
    public string Name { get; set ;}
}

public class ConcreteB : BaseClass
{
    public NumberOfPeople int { get; set }
}

So, when I create a fake instance of a BaseClass, I'm hoping to set the concrete value, where appropriate.

e.g.

Class      | Property and value, to set.
----------------------------------------
ConcreteA  | Name = "Jane"
ConcreteB  | NumberOfPeople = 3

I'm not sure how to define (in the Builder) that when currentType == typeof(ConcreteA) then do this... etc.

Update

This is how I am currently creating my fake instances:

public static T CreateAThing<T>() where T : BaseClass, new()
{
    var fixture = new Fixture();
    return fixture.Build<T>()
        .With(x => x.Id, $"things-{fixture.Create<int>()}")
        .Create();
}

where the Id is a consecutive number appended to some fixed string.

Now, when T is a ConcreteA, then I was hoping to have it do some specific logic. (like set the name to be some first name + surname) while if T is a ConcreteB, then some random number from 1 to 10.

NOTE: The reason I was doing it like this, was because I was just thinking about not repeating myself for the baseclass properties (like how I'm wanting the Id property to be things-<consecutive number>.

Open to all ideas :)

Pang
  • 9,564
  • 146
  • 81
  • 122
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647

1 Answers1

10

You can customize each concrete type individually:

fixture.Customize<ConcreteA>(c => c.With(x => x.Name, "Jane"));
fixture.Customize<ConcreteB>(c => c.With(x => x.NumberOfPeople, 3));

Subsequently, you can simply create them:

var a = fixture.Create<ConcreteA>();
var b = fixture.Create<ConcreteB>();

Console.WriteLine(a.Name);
Console.WriteLine(b.NumberOfPeople);

Prints:

Jane
3
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Gotcha -- or use `ICustomization` along with `CompositeCustomization` if i wish to reuse these cusomized concretes in multiple tests, right? – Pure.Krome Feb 05 '16 at 13:15
  • @Pure.Krome Correct. This answer, however, doesn't provide any information on how to translate a base class into a concrete class, but if you need that, then [this answer](http://stackoverflow.com/a/27247689/126014) explains how to do that. – Mark Seemann Feb 05 '16 at 13:35