Project: NullObject.For
When using dependency injection frameworks, mock objects or just good OO design, you may have code that relies on an implementation of an interface that you don’t particularly care about when testing.
For example, suppose you’re writing unit tests against a class which relies on an ILogger object. Your unit tests may not particularly care about the logger, but you can’t pass null since that’s likely to lead to null reference exceptions. After all, the component probably assumes there’s a logger somewhere, and the code would begin to look dirty if you kept checking for nulls every third line.
The simplest solution to this problem is to create a Null Object: simply, a class implementing the interface, with the body of each method empty. It doesn’t do anything, but it’s not quite null either.
As another exercise in Reflection.Emit, I set out to make an easier way to create null objects. This post describes NullObject.For, a method which generates Null Object implementation of interfaces on the fly at runtime.
Before I begin, the code for all this is in Subversion. At the time of writing, the code can be found at:
http://svn.paulstovell.net/Projects/Helpful/trunk/source/
The classes we’ll be looking at are:
Examples
Making use of this class is meant to be easy. If my AccountController class required an ILogger, but I didn’t have one available, I could just call:
var controller = new AccountController( // Class I am testing
mockCustomerRepository, // Class I am mocking
NullObject.For<ILogger>()); // Who cares about logging!
To keep things simple, the constraints are:
- Methods with interfaces as return values will return Null Objects too
- Methods with other reference types (non-interfaces) will return null
- Methods with value types will return default(T).
- Property getters will return with same rules as above
- Methods with no return type will do nothing
- Property setters will do nothing
- Events will do nothing
For example:
- NullObject.For<IEnumerable>() - the GetEnumerator() method will therefore return NullObject.For<IEnumerator>(), which will have a Current of null and MoveNext() will return false.
- NullObject.For<IDisposable>() - the dispose method will do nothing
Implementation
NullObject contains a static class with two methods - a generic For<T> method, and a non-generic version that takes the type as a parameter (in case you don’t know the type at design time). It calls through to the NullObjectBuilder class.
TemplateObjectBuilder and NullObjectBuilder are a simple template pattern implementation. TemplateObjectBuilder provides the basic algorithm (give it a bunch of interfaces, and it will loop through and generate constructors and members). NullObjectBuilder inherits it, and provides an explicit implementation for Null Objects following the rules above.
Note that apart from a few unit tests, I haven’t actually used the NullObject class yet
I wrote this out of interest rather than a pressing need for it. That said, I know a couple of places where I probably will use it now I have it. Hope you find it interesting!
Filed under: Projects

[…] NullObject.For - Paul Stovell has created a tool for unit testing which creates empty implementations of Interfaces to be used when unit testing in the situation where you don’t care about the interactions with that type - i.e Logging […]
[…] NullObject.For (Paul Stovell) […]
[…] PaulStovell.NET » NullObject.For […]
Null Object in constructor injection is a design smell, and not really the best implementation.
If the AccountController makes use of the Null Object pattern for ILogger, then the AcountController’s ILogger field should be initialized to the Null Object at the declaration of the ILogger, rather than passed in as a constructor argument.
The presence of the Null Object pattern in AcccountController for ILogger makes the ILogger dependency an optional dependency rather than a primal dependency.
Optionally dependencies can be assigned using setters since the intension of the Null Object pattern is to suggest that the dependency’s default state is the null object for its type.
Primal dependencies are always set using constructor arguments to suggest the importance and explicitness of the value of the argument, and the need for the user of the constructor to supply an explicit value.
If a class has a Null Object dependency, I shouldn’t have to worry about setting it if I’m creating an instance of the object via the constructor.
I can ensure that the Null Object dependency is set to any given non-null instance through the configuration of my dependency manager (eg: an IoC container, etc).
Hi Scott,
NullObject.For is not intended to be used in production; just for testing. In production, the AccountController requires a logger; that is to say, it is mandatory. Making it an optional paramater is not an option, as I wouldn’t sacrifice the production design of an object for the sake of lazy unit testing.
So if a null object implementation is required, how should it be passed? I certainly agree that *in production* it should be via the IOC container. But for tests, creating the IOC container is often unnecessary when I’m just testing one object.
An auto-generated NullObject implementation should never be needed for production releases of the code.
Paul
Paul,
It’s not an issue of testing or not testing, or production or not production. It’s an issue of the dependency assignment semantics for a class that uses the Null Object pattern for one of its objects.
The Null Object pattern itself indicates that the dependency’s default value is the Null Object. That’s the intended semantics of a class that uses a dependency’s null object.
The class should provide a constructor that doesn’t include any of its dependencies that use Null Object as the dependencies’ default values for the instance of the using class are initialized to the null object.
You can provide secondary constructors that provide arguments for the dependencies that use Null Object, but using setters is a clearer way of indicating through the class’s API that setting those dependencies are a secondary concern as they have an implied default value of the Null Object.
Null Objects should not be passed at all in tests. That’s the whole point of the Null Object’s influence on the protocol of initializing the class directly by hard coding calls to its constructor - as you would in tests - unless you’re using an automocker, and then you might have just glossed over this design smell entirely.
Since you called it “my AccountController” I’ll have to agree with Bellware. It will be useful, though, when dealing with code that you can’t change and that is not what is being tested.
@Scott: I think this is just a confusion of terminology. I see these null objects as simple test stubs. The semantics of the constructor are correct: the AccountController *requires* an ILogger implementation. However, for the purposes of testing, we don’t care what the implementation does.
@Paul: Perhaps you could elaborate on how NullObject.For differs from standard stubs? For example, how does this differ from using functionality in mocking frameworks such as Rhino and Moq?
>> the AccountController *requires* an ILogger implementation. However, for the purposes of testing, we don’t care what the implementation does.
Exactly.
>> Perhaps you could elaborate on how NullObject.For differs from standard stubs?
The main difference with mock objects is that you can find yourself writing more code than needed. For example, a class might require an IEnumerable somewhere, but you don’t need it for testing. So you try to pass a mock object, only the mock object expects to call GetEnumerator and iterate over the items. The mock object in this case would return “null”, which would break the calling code, even though GetEnumerator should never return null.
Other than those scenarios, though, mock objects would probably work. This just seemed more lightweight and “nicer”, and it was fun to implement
@Scott
> The Null Object pattern itself indicates that the dependency’s
> default value is the Null Object
Not sure this is true to be honest, I just see null object as a do-nothing implementation.
@Paul
This is perhaps off-topic but I don’t particularly like seeing an ILogger in a constructor, it’s not really telling me much about the design. I’d prefer to use setter injection, especially if I’m using Windosr and can use the logging facility. Thoughts?
Colin,
What can I say… If you don’t see it that way, then you don’t see it that way. That doesn’t really have much effect on this issue’s inherent truth.
By convention, a field that will have a null object as it’s value will be initialized to the null object value during the containing class’s initialization.
You certainly **can** do something different, and sometimes you might want to, but it’s not the common case.
Very useful set of classes for automating a common chore. One typo I ran into almost at once, though (shown as patch/diff from a slightly over 12 hour old download of http://svn.paulstovell.net/Projects/Helpful/trunk/source/BindingOriented.Helpful/ObjectGeneration/NullObjectBuilder.cs)
$ diff NullObjectBuilder.cs NullObjectBuilder2.cs
119c119
MethodInfo setterMethodInfo = propertyToImplement.GetSetMethod();
You don’t want to override the get_X method twice; the Reflection.Emit library code complains bitterly.
The patch without HTML swallowing half of it
(needs more “Preview Comment”)
$ diff NullObjectBuilder.cs NullObjectBuilder2.cs
119c119
< MethodInfo setterMethodInfo = propertyToImplement.GetGetMethod();
—
> MethodInfo setterMethodInfo = propertyToImplement.GetSetMethod();
[…] This NullObject Factory from Paul is very nice, simple and clean in its design. I really like it and I can see many uses for it, in parallel with working with your standard mocking framework or IoC Container Implementation. […]
As is always the case with Scott’s comments and posts, only his truth is The Truth.
Back in the real world, however, the actual semantic of setter injection has nothing to do with whether or not an injected dependency is a null/missing object, and has entirely (and only) to do with the fact that using setter injection informs the world that the component doesn’t even need ANY dependency set and it will get along just fine. Leave it null (or whatever the component chose to default to internally), it won’t care!
There’s the setter injection semantic over here, and there’s the null/missing object pattern over there. Conflating the issues, especially with the degree of condescension that Scott tends to apply, is helpful to no one.
Most of the confusion here seems to be centered around the use of the word “null”. Perhaps if it were called EmptyObject.For instead, things would be clearer (after all, the point of this code is to _prevent_ nulls).