0

I have the following nested classes, that are coming from XSD files generated via xsd.exe.

public class MyClass
{
    public AnotherClass[] PropertyOne; 

    public DateTime PropertyTwo; 

    public bool PropertyTwoSpecified
}

public class AnotherClass
{
    public DateTime AnotherPropertyOne

    public bool AnotherPropertyOneSpecified

    public int AnotherPropertyTwo

    public bool AnotherPropertyTwoSpecified
}

Now I would like to use AutoFixture to generate instances with synthetic data.

var fixture = new Fixture(); 
fixture.Customize(new AutoFakeItEasyCustomization());

var myClassFake = fixture.Create<MyClass>();

I know I can use .with to set single properties, but how can I set properties based on a specific pattern? Especially when this properties are nested in arrays?

I basically have to ensure that all properties ending with *Specified are getting set to true. Including the once nested into PropertyOne

Do I have to use my one reflection based method, e.g. an extension method (e.g. myClassFake.EnableAllProperties()) or is there an AutoFixture-way to achieve my goal?


Edit

I know I can use fixture.Register<bool>(() => true); to set all my bools to true. This solves my very specific problem, but still feels clumsy and not generally applicable. Still looking for the precise way to solve this.

Matthias Güntert
  • 4,013
  • 6
  • 41
  • 89
  • 1
    That dupe hammer of mine bothers me a bit; I'd much rather like to *vote* to close this as a duplicate. If the other post doesn't answer your question, though, please let me know, and I'll reopen this question again. – Mark Seemann Dec 27 '18 at 12:13
  • Unfortunately the linked post does not answer my question. I am trying to set a specific set of properties (based on a pattern) to a specific value. E.g. setting all properties ending with `*Specified` to `true` or setting all (nested) properties which name is `OID` to a specific value/generation algorithm. I hope its somehow clear what I am trying to achieve. Thanks in advance – Matthias Güntert Dec 28 '18 at 10:29
  • The `ReflectionVisitor` used in https://stackoverflow.com/a/47167338/126014 ought to be useful for that task as well, but I don't mind reopening the question... – Mark Seemann Dec 28 '18 at 10:47
  • Thx Mark. I ended up creating two implementations of `ISpecimenbuilder`. Although I am not sure if I am using the `RangedNumberRequest` the correct way. – Matthias Güntert Dec 31 '18 at 09:09

1 Answers1

1

I ended up creating two implementations of ISpecimenBuilder that work perfectly for my situation.

This one sets all boolean properties ending on *Specified to true without affecting other boolean properties.

public class SpecifiedBoolSpecimenBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;

        if (pi == null)
        {
            return new NoSpecimen();
        }

        if (pi.PropertyType != typeof(bool) || !pi.Name.EndsWith("Specified"))
        {
            return new NoSpecimen();
        }

        return true;
    }
}

This one sets a specific property to a range of random values:

public class OidSpecimenBuilder : ISpecimenBuilder
{
    public int Min { get; set; }

    public int Max { get; set; }

    public OidSpecimenBuilder(int min, int max)
    {
        this.Min = min;
        this.Max = max; 
    }

    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;

        if (pi == null)
        {
            return new NoSpecimen();
        }

        if (pi.PropertyType != typeof(long) || pi.Name != "OID")
        {
            return new NoSpecimen();
        }

        return context.Resolve(new RangedNumberRequest(typeof(long), Min, Max));
    }
}
Matthias Güntert
  • 4,013
  • 6
  • 41
  • 89