Important pattern in C#
While programming, one sometimes needs static methods - methods that cannot meaningfully be associated with an object (a class instance). One example that comes to mind is Math.Abs, but Factory.CreateCustomer might be another. On the other hand, static methods make the methods that use them hard to test - what do you do if you try to test a method that calls Factory.CreateCustomer()? You don't want it to do that, you might want to return a fake customer, or null, or a NullCustomer - any of a number of choices.
One solution - the most recommended one, in fact, as far as I can tell - is to extract the method in an interface (IFactory.CreateCustomer) and pass an instance of that interface to either the constructor of the class under test, or directly to the tested method. Which is nice, except sometimes you can't alter the constructor of a class (like Pages in ASP.NET and Entities when working with Linq to Sql), and passing the interface to each method looks somewhat ugly.
A few days ago I found another method (I think it was on Ayende's blog, but I'm not sure):
This declares FindCustomer as a delegate to a function taking a nullable int (the customer ID) and returning a Customer, and initializes this delegate to point to a specific function. However, and here is the great part, nothing prevents one from overwriting this function in testing to return a mock customer or whatever.
It's too early for me to tell if this is a great idea or a bad one, so I might change my mind later; but so far I'm pleased with it.
One solution - the most recommended one, in fact, as far as I can tell - is to extract the method in an interface (IFactory.CreateCustomer) and pass an instance of that interface to either the constructor of the class under test, or directly to the tested method. Which is nice, except sometimes you can't alter the constructor of a class (like Pages in ASP.NET and Entities when working with Linq to Sql), and passing the interface to each method looks somewhat ugly.
A few days ago I found another method (I think it was on Ayende's blog, but I'm not sure):
- public static class Factory
- {
- public static Func<int?, Customer> FindCustomer = customerID => GetDB().FindCustomer(CustomerID);
- }
This declares FindCustomer as a delegate to a function taking a nullable int (the customer ID) and returning a Customer, and initializes this delegate to point to a specific function. However, and here is the great part, nothing prevents one from overwriting this function in testing to return a mock customer or whatever.
It's too early for me to tell if this is a great idea or a bad one, so I might change my mind later; but so far I'm pleased with it.
Comments