4

I'm proposing using AutoFixture and AutoFixture.xUnit at our company, and have gotten the mandate that for certain objects and fields they want random data that is formatted in an expected way. For example, they want PersonName to only populate with realistic names (instead of GUIDs) and PhoneNumber to only make strings that look like phone numbers. But they DON'T want to add data annotations to the actual objects enforcing this, they would just like the test data generated by AutoFixture to be pretty.

I've dealt a bit with ICustomize classes to implement greedy constructor behavior on a few classes. Is there a similar way to override the data generation for specific objects? To (for example) pull names from a list, or generate data to follow a certain regular expression? (keeping in mind that I can't actually add those regular expressions as attributes on the model)

Riplikash
  • 843
  • 8
  • 27
  • 1
    Here's a PoC: http://blog.ploeh.dk/2010/11/22/IntegratingAutoFixturewithObjectHydrator – Mark Seemann Oct 08 '14 at 03:12
  • That was very interesting and helpful, thank you. Unfortunately, at least as it is set up in the blog post, it doesn't seem to know what to do with items that come in through the constructor. I'm going to keep looking for ways to do customization on a per-class basis and hopefully ObjectHydrator to generate the data. – Riplikash Oct 08 '14 at 19:52
  • In the blog post, it's targeting `PropertyInfo` objects. Try targeting `ParameterInfo` objects instead, and you should be good to go. – Mark Seemann Oct 08 '14 at 20:49
  • That sounds perfect, but I'm having a hard time figuring out how to do that, at least without modifying the ObjectHydrator source. From what I can tell, I can't just change instances in the example to ParameterInfo because they are getting compared to IMap (in the ObjectHydrator) which defines PropertyInfo. Any suggestions on what I would need to do to target ParameterInfo? – Riplikash Oct 09 '14 at 16:55
  • Ah, right, it's been a long time since I looked at that code. You're right. ObjectHydrator looks like it's coupled to PropertyInfo... – Mark Seemann Oct 10 '14 at 05:45

1 Answers1

2

Ok, solved my problem.

Object generation for a given class type can be accomplished via the Fixture.Register method. You can make a method that returns the type you want to override and that will be used instead of the default.

To get meaningful data I just used Faker.Net.

I got the solution Mark pointed out working, and really liked it for general POJOs, but in my case many of my objects had properties that could only be set via the constructor or aggregate setters (like ChangeContactInfo), so unfortunately I needed something a bit more targeted. Here is an example of my solution implementing a name and address generation override:

public class CustomObjectGeneration : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Register(GenerateAddress); 
        fixture.Register(GeneratePersonName);
    }

    private Address GenerateAddress()
    {
        return new Address(Faker.Address.StreetAddress(), Faker.Address.SecondaryAddress(), Faker.Address.City(),
            Faker.Address.ZipCode(), Faker.Address.UsState(), Faker.Address.Country());
    }

    private PersonName GeneratePersonName()
    {

        return new PersonName(Faker.Name.Prefix(), Faker.Name.First(), Faker.Name.First(), Faker.Name.Last(), Faker.Name.Suffix());
    }

}
Riplikash
  • 843
  • 8
  • 27