ploeh blog danish software design
Delegates Are Anonymous Interfaces
This is really nothing new, but I don't think I've explicitly stated this before: It makes a lot of sense to view delegates as anonymous one-method interfaces.
Many people liken delegates to function pointers. While that's probably correct (I wouldn't really know), it's not a very object-oriented view to take - at least not when we are dealing with managed code. To me, it makes more sense to view delegates as anonymous one-method interfaces.
Lets consider a simple example. As always, we have the ubiquitous MyClass with its DoStuff method. In this example, DoStuff takes as input an abstraction that takes a string as input and returns an integer - let's imagine that this is some kind of Strategy (notice the capital S - I'm talking about the design pattern, here).
In traditional object-oriented design, we could solve this by introducing the IMyInterface type:
public interface IMyInterface { int DoIt(string message); }
The implementation of DoStuff is simply:
public string DoStuff(IMyInterface strategy) { return strategy.DoIt("Ploeh").ToString(); }
Hardly rocket science…
However, defining a completely new interface just to do this is not really necessary, since we could just as well have implemented DoStuff with a Func<string, int>:
public string DoStuff(Func<string, int> strategy) { return strategy("Ploeh").ToString(); }
This not only frees us from defining a new interface, but also from implementing that interface to use the DoStuff method. Instead, we can simply pass a lambda expression:
string result = sut.DoStuff(s => s.Count());
What's most amazing is that RhinoMocks understands and treats delegates just like other abstract types, so that we can write the following to treat it as a mock:
// Fixture setup Func<string, int> mock = MockRepository.GenerateMock<Func<string, int>>(); mock.Expect(f => f("Ploeh")).Return(42); var sut = new MyClass(); // Exercise system string result = sut.DoStuff(mock); // Verify outcome mock.VerifyAllExpectations(); // Teardown
Whenever possible, I prefer to model my APIs with delegates instead of one-method interfaces, since it gives me greater flexibility and less infrastructure code.
Obviously, this technique only works as long as you only need to abstract a single method. As soon as your abstraction needs a second method, you will need to introduce a proper interface or, preferably, an abstract base class.
The AutoFixture Builder
Until now, I've shown you how you can make wholesale adjustments or customizations to an entire Fixture instance, effectively changing the way it creates all instances of a particular type.
In some scenarios, you'd rather want to customize how a single instance is created without influencing other instances of the same type. For this purpose, AutoFixture includes a class called ObjectBuilder<T> that can be used to do exactly that.
The easiest way to get an instance of this class is by calling Build on a Fixture instance. This will give you an instance of ObjectBuilder<T> that you can use to customize the build steps. When you are done, CreateAnonymous returns the built instance.
var mc = fixture.Build<MyClass>().CreateAnonymous();
This particular example doesn't define any customizations, so it's equivalent to
var mc = fixture.CreateAnonymous<MyClass>();
In fact, Fixture.CreateAnonymous is little more than a convenience method wrapping an ObjectBuilder (there's a few extra differences, but that's a topic for another post).
It's worth noting that the object specified by the type parameter to the Build method is first created when you call CreateAnonymous.
In future posts I'll demonstrate how to use the Build method to customize individual anonymous variables.
SyncOrchestrator.Synchronize() Throws COMException When Unit Testing
This post describes a particular problem I ran into when working with the Microsoft Sync Framework. Since I found a solution, I'm sharing it here to help others. If you are not having this particular problem, it's quite safe to skip reading the rest of the post :)
While developing a SyncProvider, I wanted to create and execute a series of Integration Tests to drive my development effort. In order to do that, I wrote a simple test that simply created a SyncOrchestrator instance and invoked its Synchronize method.
Running this test gave me this error message:
“Microsoft.Synchronization.SyncException: Retrieving the COM class factory for component with CLSID {A7B3B4EE-925C-4D6C-B007-A4A6A0B09143} failed due to the following error: 80040154. ---> System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {A7B3B4EE-925C-4D6C-B007-A4A6A0B09143} failed due to the following error: 80040154.”
It's not often I see a COMException these days, so I was initially baffled. Since the Sync Framework also has an unmanaged API, this is really not surprising, but that didn't help me solve my problem.
What was even weirder was that when I tried running the same code in my application, this exception was not being thrown.
It took me a couple of hours to figure out what the problem was.
Here's a little hint: I'm running Windows Vista x64.
No: The issue is not that I'm running Vista :)
Even on x64, Visual Studio runs as a 32-bit process, and so does MSTest. Since my code was compiled to Any CPU, the application itself was running in a 64-bit process, whereas my unit test was running in a 32-bit process.
I tried changing my build output to x86, and now the application started throwing the same exception as the unit test did.
In other words: When running in a 64-bit process, everything worked as intended. When running in a 32-bit process, a COMException was thrown.
As it turned out, I had only installed the 64-bit version of the Sync Framework, and even though the SDK seems to contain builds for the other architectures as well, the COM Server wasn't properly registered for 32-bit use.
To resolve this issue, I downloaded and installed the x86 version of the Sync Framework as well, and the problem went away.
If you are having the same problem, I hope this post helps you resolve it.
Comments
Thank you for your message - I am happy that my post was helpful to you.
I was trying to find out why SharePoint Workspace did not work on my workstation. It was failing with the "Class not found" 80040154 error, and I found your article with a Google search on the CLSID. Installing Microsoft Sync Framework 1.0 SP1 fixed the problem, and I would never have known where to look without your article.
AutoFixture .8.1 Released
Today I've created a new release (.8.1 for lack of a better version number) of AutoFixture. While it contains some breaking changes, they all relate to features that I have yet to cover here on the blog - in other words: All the examples that I've posted so far are still valid.
AutoFixture As Fixture Object
Dear reader, I hope you are still with me!
After eight posts of AutoFixture feature walkthroughs, I can't blame you for wondering why this tool might even be relevant to you. In this post, we'll finally begin to look at how AutoFixture can help you towards Zero-Friction TDD!
In an earlier post, I described how the Fixture Object pattern can help you greatly reduce the amount of test code that you have to write. Since AutoFixture was designed to act as a general-purpose Fixture Object, it can help you reduce the amount of test code even further, letting you focus on specifying the behavior of your SUT.
In that former post, the original example was this complex test that I will repeat in it's entirety for your benefit (or horror):
[TestMethod] public void NumberSumIsCorrect_Naïve() { // Fixture setup Thing thing1 = new Thing() { Number = 3, Text = "Anonymous text 1" }; Thing thing2 = new Thing() { Number = 6, Text = "Anonymous text 2" }; Thing thing3 = new Thing() { Number = 1, Text = "Anonymous text 3" }; int expectedSum = new[] { thing1, thing2, thing3 }. Select(t => t.Number).Sum(); IMyInterface fake = new FakeMyInterface(); fake.AddThing(thing1); fake.AddThing(thing2); fake.AddThing(thing3); MyClass sut = new MyClass(fake); // Exercise system int result = sut.CalculateSumOfThings(); // Verify outcome Assert.AreEqual<int>(expectedSum, result, "Sum of things"); // Teardown }
This test consists of 18 lines of code.
Using the Fixture Object pattern, I was able to cut that down to 7 lines of code, which is a 61% improvement (however, the downside was an additional 19 lines of (reusable) code for MyClassFixture, so the benefit can only be reaped when you have multiple tests leveraged by the same Fixture Object. This was all covered in the former post, to which I will refer you).
With AutoFixture, we can do much better. Here's a one-off rewrite of the unit test using AutoFixture:
[TestMethod] public void NumberSumIsCorrect_AutoFixture() { // Fixture setup Fixture fixture = new Fixture(); IMyInterface fake = new FakeMyInterface(); fixture.Register<IMyInterface>(() => fake); var things = fixture.CreateMany<Thing>().ToList(); things.ForEach(t => fake.AddThing(t)); int expectedSum = things.Select(t => t.Number).Sum(); MyClass sut = fixture.CreateAnonymous<MyClass>(); // Exercise system int result = sut.CalculateSumOfThings(); // Verify outcome Assert.AreEqual<int>(expectedSum, result, "Sum of things"); // Teardown }
In this test, I map the concrete fake instance to the IMyInterface type in the fixture object, and then use its ability to create many anonymous instances with one method call. Before exercising the SUT, I also use the fixture instance as a SUT Factory.
Apart from AutoFixture (and FakeMyInterface, which is invariant for all variations, and thus kept out of the comparison), this test stands alone, but still manages to reduce the number of code lines to 10 lines - a 44% improvement! In my book, that's already a significant gain in productivity and maintainability, but we can do better!
If we need to test MyClass repeatedly in similar ways, we can move the common code to a Fixture Object based on AutoFixture, and the test can be refactored to this:
[TestMethod] public void NumberSumIsCorrect_DerivedFixture() { // Fixture setup MyClassFixture fixture = new MyClassFixture(); fixture.AddManyTo(fixture.Things); int expectedSum = fixture.Things.Select(t => t.Number).Sum(); MyClass sut = fixture.CreateAnonymous<MyClass>(); // Exercise system int result = sut.CalculateSumOfThings(); // Verify outcome Assert.AreEqual<int>(expectedSum, result, "Sum of things"); // Teardown }
Now we are back at 7 lines of code, which is on par with the original Fixture Object-based test, but now MyClassFixture is reduced to 8 lines of code:
internal class MyClassFixture : Fixture { internal MyClassFixture() { this.Things = new List<Thing>(); this.Register<IMyInterface>(() => { var fake = new FakeMyInterface(); this.Things.ToList().ForEach(t => fake.AddThing(t)); return fake; }); } internal IList<Thing> Things { get; private set; } }
Notice how I've moved the IMyInterface-to-FakeMyInterface mapping to MyClassFixture. Whenever it's asked to create a new instance of IMyInterface, MyClassFixture makes sure to add all the Thing instances to the fake before returning it.
Compared to the former Fixture Object of 19 lines, that's another 58% improvement. Considering some of the APIs I encounter in my daily work, the above example is even rather simple. The more complex and demanding your SUT's API is, the greater the gain from using AutoFixture will be, since it's going to figure out much of the routine stuff for you.
With this post, I hope I have given you a taste of the power that AutoFixture provides. It allows you to focus on specifying the behavior of your SUT, while taking care of all the infrastructure tedium that tends to get in the way.
Anonymous Sequences With AutoFixture
When writing unit tests you often need to deal with sequences and collections, populating lists with anonymous data as part of setting up a Fixture.
This is easy to do with AutoFixture. While you can obviously create a simple loop and call CreateAnonymous from within the loop, AutoFixture provides some convenient methods for working with sequences.
Equivalent to the CreateAnonymous method, the Fixture class also includes the CreateMany method that creates a sequence of anonymous variables. CreateManyAnonymous might have been a more concise and consistent name for the method, but I felt that this was a bit too verbose.
This will create an IEnumerable<string>:
Fixture fixture = new Fixture(); var strings = fixture.CreateMany<string>();
Obviously, you can create sequences of whatever type you want, as long as AutoFixture can figure out how to create instances of the type:
var myInstances = fixture.CreateMany<MyClass>();
Being able to create sequences of anonymous data is nice, but sometimes you need to add multiple anonymous items to an existing list (particularly if that list is a read-only property of your SUT).
To support that scenario, the Fixture class also has the AddManyTo method that can be used like this:
var list = new List<MyClass>(); fixture.AddManyTo(list);
This simply creates many anonymous MyClass instances and adds them all to the list. Once more, AddManyAnonymousTo might have been a more precise name, but again I chose a less verbose alternative.
If you want more control over how the instances are created, a more explicit overload of AddManyTo gives you that.
var list = new List<int>(); var r = new Random(); fixture.AddManyTo(list, () => r.Next());
The above examples adds many random numbers to the list of integers, since the second parameters is a Func<T> used to create the instances.
By default, these methods all create 3 anonymous variables when called, since 3 is a good equivalent for many. If you want a different number of instances to be created, you can modify the RepeatCount property.
fixture.RepeatCount = 10; var sequence = fixture.CreateMany<MyClass>();
The above example will create an IEnumerable<MyClass> with 10 anonymous MyClass instances, while this will add 7 anonymous instances to the list variable:
var list = new List<MyClass>(); fixture.RepeatCount = 7; fixture.AddManyTo(list);
AutoFixture provides some convenient methods for creating and managing collections of anonymous data. While it may seem simple (and it is), in a future post I will demonstrate how it can save you quit a bit of infrastructure code, and enable you to write unit tests that are shorter, more concise and more maintainable.
Managing Loosely Coupled Projects
Udi recently posted an article on managing loose coupling in Visual Studio. While I completely agree, this is a topic that deserves more detailed treatment. In particular, I'd like to expand on this statement:
"In fact, each component could theoretically have its own solution"
This is really the crux of the matter, although in practical terms, you'd typically need at least a couple of projects per component. In special cases, a component may truly be a stand-alone component, requiring no other dependencies than what is already in the BCL (in fact, AutoFixture is just such a component), but most components of more complex software have dependencies.
Even when you are programming against interfaces (which you should be), these interfaces will normally be defined in other projects.
A component may even use multiple interfaces, since it may be implementing some, but consuming others, and these interfaces may be defined in different projects. This is particularly the case with Adapters.
Finally, you should have at least one unit test project that targets your component.
In essence, while the exact number of projects you need will vary, it should stay small. In the figure above, we end up with five projects, but there's also quite a few abstractions being pulled in.
As a rule of thumb I'd say that if you can't create an .sln file that contains less than ten projects to work on any component, you should seriously consider your decoupling strategy.
You may choose to work with more than ten projects in a solution, but it should always be possible to create a solution to work with a single component, and it should drag only few dependencies along.
Dealing With Constrained Input
As a response to my description of how AutoFixture creates objects, Klaus asked:
“[What] if the constructor of ComplexChild imposes some kind of restriction on its parameter? If, for example, instead of the "name" parameter, it would take a "phoneNumber" parameter (as a string), and do some format checking?”
Now that we have covered some of the basic features of AutoFixture, it's time to properly answer this excellent question.
For simplicity's sake, let's assume that the phone number in question is a Danish phone number: This is pretty good for example code, since a Danish phone number is essentially just an 8-digit number. It can have white space and an optional country code (+45), but strip that away, and it's just an 8-digit number. However, there are exceptions, since the emergency number is 112 (equivalent to the American 911), and other 3-digit special numbers exist as well.
With that in mind, let's look at a simple Contact class that contains a contact's name and Danish phone number. The constructor might look like this:
public Contact(string name, string phoneNumber) { this.Name = name; this.PhoneNumber = Contact.ParsePhoneNumber(phoneNumber); }
The static ParsePhoneNumber method strips away white space and optional country code and parses the normalized string to a number. This fits the scenario laid out in Klaus' question.
So what happens when we ask AutoFixture to create an instance of Contact? It will Reflect over Contact's constructor and create two new anonymous string instances - one for name, and one for phoneNumber. As previously described, each string will be created as a Guid prepended with a named hint - in this case the argument name. Thus, the phoneNumber argument will get a value like "phoneNumberfa432351-1563-4769-842c-7588af32a056", which will cause the ParsePhoneNumber method to throw an exception.
How do we deal with that?
The most obvious fix is to modify AutoFixture's algorithm for generating strings. Here an initial attempt:
fixture.Register<string>(() => "112");
This will simply cause all generated strings to be "112", including the Contact instance's Name property. In unit testing, this may not be a problem in itself, since, from an API perspective, the name could in principle be any string.
However, if the Contact class also had an Email property that was parsed and verified from a string argument, we'd be in trouble, since "112" is not a valid email address.
We can't easily modify the string generation algorithm to fit the requirements for both a Danish telephone number and an email address.
Should we then conclude that AutoFixture isn't really useful after all?
On the contrary, this is a hint to us that the Contact class' API could be better. If an automated tool can't figure out how to generate correct input, how can we expect other developers to do it?
Although humans can make leaps of intuition, an API should still go to great lengths to protect its users from making mistakes. Asking for an unbounded string and then expecting it to be in a particular format may not always be the best option available.
In our particular case, the Value Object pattern offers a better alternative. Our first version of the DanishPhoneNumber class simply takes an integer as a constructor argument:
public DanishPhoneNumber(int number) { this.number = number; }
If we still need to parse strings (e.g. from user input), we could add a static Parse, or even a TryParse, method and test that method in isolation without involving the Contact class.
This neatly solves our original issue with AutoFixture, since it will now create a new instance of DanishPhoneNumber as part of the creation process when we ask for an anonymous Contact instance.
The only remaining issue is that by default, the number fed into the DanishPhoneNumber instance is likely to be considerably less than 112 - actually, if no other Int32 instances are created, it will be 1.
This will be a problem if we modify the DanishPhoneNumber constructor to look like this:
public DanishPhoneNumber(int number) { if ((number < 112) || (number > 99999999)) { throw new ArgumentOutOfRangeException("number"); } this.number = number; }
Unless a unit test has already caused AutFixture to previously create 111 other integers (highly unlikely), CreateAnonymous<Contact> is going to throw an exception.
This is easy to fix. Once again, the most obvious fix is to modify the creation algorithm for integers.
fixture.Register<int>(() => 12345678);
However, this will cause that particular instance of Fixture to return 12345678 every time you ask it to create an anonymous integer. Depending on the scenario, this may or may not be a problem.
A more targeted solution is to specifically address the algorithm for generating DanishPhoneNumber instances:
fixture.Register<int, DanishPhoneNumber>(i => new DanishPhoneNumber(i + 112));
Here, I've even used the Register overload that automatically provides an anonymous integer to feed into the DanishPhoneNumber constructor, so all I have to do is ensure that the number falls into the proper range. Adding 112 (the minimum) neatly does the trick.
If you don't like the hard-coded value of 112 in the test, you can use that to further drive the design. In this case, we can add a MinValue to DanishPhoneNumber:
fixture.Register<int, DanishPhoneNumber>(i => new DanishPhoneNumber(i + DanishPhoneNumber.MinValue));
Obvously, MinValue will also be used in DanishPhoneNumber's constructor to define the lower limit of the Guard Clause.
In my opinion, a good API should guide the user and make it difficult to make mistakes. In many ways, you can view AutoFixture as an exceptionally dim user of your API. This is the reason I really enjoyed receiving Klaus' original question: Like other TDD practices, AutoFixture drives better design.
Speaking at 7N IT Conference 2009
At May 12 2009 I'll be speaking at 7N's IT Konference 2009 (in Danish, so that's no spelling error). You can read the program here.
The topic of my talk will be TDD patterns and terminology, so I'll discuss Fixtures, Stubs, Mocks and the like. As always, xUnit Test Patterns will form the basis of my vocabulary.
Of the other speakers, I'm particularly looking forward to hear my good friend Martin Gildenpfennig from Ative speak!
Replacing AutoFixture's Default Algorithms
Several times in my previous AutoFixture posts, I've insinuated that you can change the algorithms used for creating strings, numbers and so on, if you don't like the defaults.
One way you can do this is by simply using the Register method that I introduced in my previous post. Let's say that you want to replace the string algorithm to simply return a specific string:
fixture.Register<string>(() => "ploeh");
No matter how many times you'll call CreateAnonymous<string> on that particular fixture object, it will always return ploeh.
The Register method is really only a type-safe convenience method that wraps access to the TypeMappings property. TypeMappings is just a Dictionary of types mapped to functions. By default, the Fixture class has a set of pre-defined TypeMappings for primitive types such as strings, numbers and booleans, so you could access the function used to generate strings by indexing into this Dictionary with the System.String type.
Equivalent to the above example, you could alternatively replace the string algorithm like this:
fixture.TypeMappings[typeof(string)] = s => "fnaah";
Instead of using the Register method, I here assign a lambda expression directly to the key identified by the System.String type. This is what the Register method does, so the result is exactly the same.
However, you may have noticed that by accessing TypeMappings directly, the signature of the function is different. The Register method takes a Func<T>, whereas the TypeMappings Dictionary expects a Func<object, object>. As you can see, the Register method is more type-safe, but the TypeMappings Dictionary gives you a chance to utilize the optional seed that one of the CreateAnonymous overloads takes.
You could, for example, do this:
fixture.TypeMappings[typeof(string)] = s => string.Format((string)s, new Random().Next(100));
Although this particular algorithm has a built-in weakness (can you spot it?), we can now use the seed to provide a format string, like this:
string result = fixture.CreateAnonymous("Risk: {0}%");
which will yield a result like Risk: 32%.
When I designed the extensibility mechanism for AutoFixture, I seriously considered defining an interface that all TypeMappings had to implement, but I ended up preferring a Func<object, object> instead, since this allows you to redefine a particular algorithm inline in a test by using an anonymous delegate or lambda expression, and you can also reuse an existing algorithm, as long as it fits the signature.
Comments
We shouldn't believe that delegates are unlike a function pointer just because the latter is not object-oriented. The shoe ... fits. Furthermore, I would argue that an anonymous one-method interfaces is not a first-class object-oriented concept; we can describe it with words, but I doubt that you will find any of the non-.NET literature talking about such a thing. Well ... I will grant that mention might be made under a description of the command pattern.
"Obviously, this technique only works as long as you only need to abstract a single method."
Yes. Then we are in trouble and we didn't even swim that far from shore.
What was the problem? We focussed too much on a method and we ignored the interface. An interface defines the contract of which the method is only a part. The contract is identified by the name of the interface. There is no contract defined by method signatures. "Takes an int and a double and returns a string" doesn't mean anything.
In summary, focussing on the method is every bit as dirty as ... function pointers.
Sincerely,
jonnie savell