Anonymous delegates in AutoFixture
01/08/2011
I’m excited to announce that AutoFixture now officially supports delegates in the main trunk up on CodePlex.
If you aren’t familiar with AutoFixture, let me give you the pitch:
Does this sound interesting to you? In that case head over to the AutoFixture CodePlex site and find out more. You’ll be glad you did.
For those of you already familiar with AutoFixture, the newly added support for delegates means that every time AutoFixture is asked to create an anonymous instance of a delegate type (or more precisely a delegate specimen), it will actually return one, instead of throwing an exception.
So, you’ll be able to say things like:
public delegate void MyDelegate(); var fixture = new Fixture(); var delegateSpecimen = fixture.CreateAnonymous<MyDelegate>();
and get back a delegate pointing to a dynamically generated method, whose signature matches the one of the requested delegate type. In other words AutoFixture will satisfy the requests for delegates by providing a method specimen.
That’s cool, but it may leave you wondering: what on Earth does a method specimen do when it gets invoked? Well, in order to answer that question, we need to look at the signature of the delegate that was requested in the first place. The rule basically says:
- If the signature of the requested delegate has a return value (i.e. it’s a function), the method specimen will always return an anonymous value of the return type.
- If the signature of the requested delegate doesn’t have a return value (i.e. it’s an action) the returned method specimen will have an empty body.
This principle is best illustrated by examples. Consider the following code snippet:
var fixture = new Fixture(); var funcSpecimen = fixture.CreateAnonymous<Func<string>>(); var result = funcSpecimen(); // result = "fd95320f-0a37-42be-bd49-3afbbe089d9d"
In this example, since the signature of the requested delegate has a return value of type String, the result variable will contain an anonymous string value, which in AutoFixture usually translates into a GUID.
On the other hand, if requested delegate didn’t have a return value, invoking the anonymous delegate would do just about nothing:
var fixture = new Fixture();
var actionSpecimen = fixture.CreateAnonymous<Action<string>>();
actionSpecimen("whatever"); // no-op
Note that in both cases any input arguments passed to the anonymous delegate will be ignored, since they don’t have any impact on the generated method specimen.
Now, if you’re using AutoFixture from its NuGet package (which, by the way, you should) you’ll have to wait until the next release to get this feature. However, taking advantage of it with the current version of AutoFixture requires a minimal amount of effort. Just grab the DelegateGenerator.cs class from AutoFixture’s main trunk on CodePlex and include it in your project. You’ll then be able to add support for delegates to your Fixture instance by simply saying:
var fixture = new Fixture(); fixture.Customizations.Add(new DelegateGenerator());
You can even wrap that up in a Customization to make it more centralized and keep your test library DRY:
public class DelegateCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
if (fixture == null)
{
throw new ArgumentNullException("fixture");
}
fixture.Customizations.Add(new DelegateGenerator());
}
}
Before finishing this off, let me give you a more concrete example that shows how this is useful in a real world scenario. Keeping in mind that delegates offer a pretty terse way to implement the Strategy Design Pattern in .NET, consider this implementation of the IEqualityComparer<T> interface:
public class EqualityComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> equalityStrategy;
private readonly Func<T, int> hashCodeStrategy;
public EqualityComparer(Func<T, T, bool> equalityStrategy, Func<T, int> hashCodeStrategy)
{
if (equalityStrategy == null)
{
throw new ArgumentNullException("equalityStrategy");
}
if (hashCodeStrategy == null)
{
throw new ArgumentNullException("hashCodeStrategy");
}
this.equalityStrategy = equalityStrategy;
this.hashCodeStrategy = hashCodeStrategy;
}
public bool Equals(T x, T y)
{
return equalityStrategy(x, y);
}
public int GetHashCode(T obj)
{
return hashCodeStrategy(obj);
}
}
That’s a nice flexible class that, by allowing to specify the comparison logic in the form of delegates, is suitable in different scenarios. Before the support for delegates was added, however, having AutoFixture play along with this class in the context of unit testing would be quite problematic. The tests would, in fact, fail consistently with a NotSupportedException, since the constructor of the EqualityComparer class requires the creation of two delegates.
Luckily, this is not a problem anymore.




02/08/2011 at 13:05
Thanks for the writeup!
Until AutoFixture 2.2. is out, you can get the latest build, including NuGet packages, from here: http://teamcity.codebetter.com/project.html?projectId=project129&tab=projectOverview
02/08/2011 at 13:15
@Mark That’s even better. Thanks for pointing that out :)
03/08/2011 at 07:37
Very well written article (and source code)! Keep up the good work!
03/08/2011 at 09:03
@Nikos Thanks! :)