AutoPoco v0.1 Released

Published on 2010-4-6

** Update: Version 0.2 Now Released**

The product of one weekend and a bank holiday's code, I wanted to simplify the way we were generating test data for our tests, and writing a class called <ObjectName>Builder with lots of permutations for overriding various properties for every single object I wanted to generate was getting tedious.

I also wanted to have a go at writing something that exposed a fluent interface that could be extended using extension methods, and combined convention with configuration to do its job in an easily configurable fashion.

Combining these two into a project was a fun thing to do, whether the project is of any use to anybody else is irrelevant, but you don't know unless you push these things out...

http://autopoco.codeplex.com

Using it should be self explanatory, but here is a quick overview of what AutoPoco attempts to achieve.

Configuring a factory
A factory can be created once and then re-used by tests (if you so wish), a factory is just a configured instance of AutoPoco and has therefore performed some of the more expensive reflection operations ahead of use.

Using the default conventions, any recognised properties on an object will automatically be populated with an instance of that property type, and this will obviously recurse down the object graph.

var factory = AutoPocoContainer.Configure(x =>
            {
                x.Conventions(c =>
                {
                    // Map all public properties + fields
                    // Ensure  we don't end up with nulls
                    c.UseDefaultConventions();
                });

                // Include the simple user type
                x.Include<SimpleUser>()
                    // Expicitly set data sources for its properties
                    .Setup(c => c.EmailAddress).Use<EmailAddressSource>()
                    .Setup(c => c.FirstName).Use<FirstNameSource>()
                    .Setup(c => c.LastName).Use<LastNameSource>();

                // Include the user role type (used by User.Role)
                // Set the name as a string with a length between 5 and 10
                // Note: Random is an extension method and only gets provided if the property/field is a string
                x.Include<SimpleUserRole>()
                    .Setup(c => c.Name).Random(5, 10);

                // Include these types, but use the default conventions to auto-set properties/fields
                x.Include<SimpleFieldClass>();
                x.Include<SimplePropertyClass>();
                x.Include<DefaultPropertyClass>();
                x.Include<DefaultFieldClass>();
            });

Creating a session
A session should be created once per test (or more), and will use data sources scoped to that session to populate requested objects. An example of this would be a source configured to create unique ids for "database" objects - each id would be unique across that session, but creating another session would mean that session had its own data source back at the original state.
Don't worry, you don't need to understand this, it's just there for those that want it.

var session = factory.CreateSession();

Creating Objects
This is the important bit - any number of objects should capable of being be created from the session, with the ability to easily override any of the properties on those objects

            // Get a single default user
            // User.Role will be set automatically by AutoPoco
            // User.EmailAddress will be a valid e-mail address
            SimpleUser singleDefaultUser = mSession.With<SimpleUser>().Get();
            
            // Get 100 users
            // They all have different e-mail address
            // They all have different first names
            // They all have different last names
            SimpleUser[] users = mSession.With<SimpleUser>().Get(100);
            
            // Create a role
            SimpleUserRole sharedRole = mSession.With<SimpleUserRole>().Get();
            
            // Impose that role on 100 users
            // Those 100 users still have different e-mail addresses etc etc
            SimpleUser[] usersSharingRole = mSession.With<SimpleUser>()
                .Impose(x => x.Role, sharedRole)
                .Get(100);

I think this is quite neat and tidy,  although there are lots of features missing (ability to populate collections, a convention to deal with enums, a convention to deal with inheritance - and lots of extension methods to allow the easy manual configuration of all of those things.

I'll add them as I need them or as they are requested. This is my framework for my use, but you're all welcome to use and contribute to it too.

This used to ask if you wanted to hire me

But chances are I'm not available, as I'm busy shipping stuff.

Drop me an e-mail anyway, as I like interesting problems.

Get in touch

blog comments powered by Disqus