How to Think About the “new” Operator with Respect to Unit Testing

Unit Testing as the name implies asks you to test a Class (Unit) in isolation.

If your code mixes Object Construction with Logic you will never be able to achieve isolation.

In order to unit-test you need to separate object graph construction from the application logic into two different classes

The end goal is to have either: classes with logic OR classes with “new” operators.

Unit-Testing as the name implies is testing of a Unit (most likely a Class) in isolation. Suppose you have a class House. In your JUnit test-case you simply instantiate the class House, set it to a particular state, call the method you want to test and then assert that the class’ final state is what you would expect. Simple stuff really…

If you look at House closely you will realize that this class is a leaf of your application. By leaf I mean that it is the end of the dependency graph, it does not reference any other classes. As such all leafs of any code base are easy to tests, because the dependency graph ends with the leaf. But testing classes which are not leafs can be a problem because we may not be able to instantiate the class in isolation.

In this updated version of House it is not possible to instantiate House without the Kitchen. The reason for this is that the new operator of Kitchen is embedded within the House logic and there is nothing we can do in a test to prevent the Kitchen from getting instantiated. We say that we are mixing the concern of application instantiation with concern of application logic. In order to achieve true unit testing we need to instantiate realHouse with a fakeKitchen so that we can unit-test the House in isolation.

Notice how we have removed the new operator from the application logic. This makes testing easy. To test we simply new-up a real House and use a mocking framework to create a fake Kitchen. This way we can still test House in isolation even if it is not a leaf of an application graph.

But where have the new operators gone? Well, we need a factory object which is responsible for instantiating the whole object graph of the application. An example of what such an object may look like is below. Notice how all of the new operators from your applications migrate here.

As a result your main method simply asks the ApplicationBuilder to construct the object graph for you application and then fires of the application by calling a method which does work.

class Main {
public static void main(String...args) {
House house = new ApplicationBuilder().build();
house.lock();
}
}

Asking for your dependencies instead of constructing them withing the application logic is called “Dependency Injection” and is nothing new in the unit-testing world. But the reason why Dependency Injection is so important is that within unit-tests you want to test a small subset of your application. The requirement is that you can construct that small subset of the application independently of the whole system. If you mix application logic with graph construction (the new operator) unit-testing becomes impossible for anything but the leaf nodes in your application. Without Dependency Injection the only kind of testing you can do is scenario-testing, where you instantiate the whole application and than pretend to be the user in some automated way.

[...] the new operators are mixed with application logic (see: How to Think About the new Operator) then the Constructor Graph and the Collaborator Graph tend to be one and the same. However, in an [...]

[...] fell upon an excellent post by Misko Hevery where he describes how we should treat the “new” operator. He inadvertently explained Dependency Injection in a really clear and simple way using a House and [...]

[...] google) goes into much greater detail about this technique in his two fantastic blog posts entitled “How to Think About the ‘new’ Operator with Respect to Unit Testing” and “Where Have All the Singletons [...]

[...] that mean that dependency injection is wrong? NO! it means that you only did half of the work! In how to think about the new operator we go into the details why it is important to separate your business logic from the new operators. [...]

hi there! i m an as3 developper and your articles are very interesting! I am definetly ok with using factories instead of using new operator in myh class… but what if the obejcts created hav a big “tree architecture”? i mean what if the house has a kitchen whitch has a sink, which has a tap which is made of many other things… don’ t you feel like the factory method for creating this object will get you nuts?? (sorry for my poor english)

The end goal is to have either: classes with logic OR classes with “new” operators.Bullshit. If the logic includes instantiating an object, why should I always create a builder class? Not that you shouldn’t create a builder class, but it is a design decision, not a hard rule. Even if you create a builder class, who instantiates it? Will you inject it? If it is a entity class (which usually are kinda difficult to do DI with) will use black magic just to avoid calling ‘new’ to a class you only have one implementation?The end goal should be always be software qualities (maintainability, performance, availability, etc.). Techniques, patterns, or practices like testing are just tools to achieve the qualities. When they turn into your goals, you are starting to miss the point.

Those are strong words. Testable design has the property of logic factory seperation. How does one explain that to someone just starting out? If you keep this rule your code will be a lot more testable. Than when you get good at testing you will learn when you can get away with breaking it. But first is realizing that such seperation is a good thing.

“If your code mixes Object Construction with Logic you will never be able to achieve isolation.”Well, but what if the above statement was actually false? Suppose you could achieve that isolation easily in test code, so that production code could continue using the “new” operator to instantiate dependencies?

I am curious what advice you would give if the object graph is not hard-coded, as in the ‘house has-a kitchen’ example, but is more dynamic. For example, I’m currently generating a graph of linked polygonal ‘room’ objects to represent a maze. Deciding where each polygon is spatially located requires significant logic, and based on the results of that I then create a polygon object. I am unsure how best to separate out these two actions.

Maybe create the maze as a simple data structure, lists of point co-ordinates, and when that is completed, hand it over to some factor to create all the room objects?

I’m very much enjoying your articles, they are making me think. Thanks very much for the effort of writing and posting them.

Sounds like a perfect job for a factory. Factory can decide how individual objects are put together in order to build your graph. We again have a separation between the code which contains the ‘new’ operators and the resulting object graph which will presumably behave differently depending on way the object graph is put together.

My problem is then how to test the factory – it is now a mixture of extensive logic and new operators.

I don’t quite understand if you were endorsing the vague idea I mentioned, to create the maze as simple data structures (eg. lists of point coords, for example) which is well unit-tested, and then finally pass that data structure to a very dumb inner-factory that contains all the new operators, iterates through all the lists, creating ‘Room’ objects.

If your factory is sufficiently complex, you haven’t separated logic from construction.
In Jonathan’s case, I would have a TheoreticalMaze that can be tested stand-alone, and pass the TheoreticalMaze as an argument to a maze factory that builds the RoomMaze.Supposing it was necessary to construct the rooms as part of working out the maze structure: in this case, I’d supply the maze builder with a room factory. For unit testing, the room factory would be a mock factory, supplying mock rooms.

[...] I think if the Room object isn’t going to instantiate RoomID and RoomName, then the not-yet-written RoomFactory should. This way, I can keep the “new” keyword out of the domain model, except for factories. Keeping all object construction in factory classes smells right and follows Hevery’s testability advice. [...]

Here’s a problem I have with this approach: loss of encapsulation and the resulting brittleness.

For example, assume that House is modified to also have a Bathroom. In the “non-testable” version, you have to modify only one class, namely House. In the “testable” version, you have to modify two classes, both House and ApplicationBuilder.

Presumably, ApplicationBuilder would also be responsible for, say, Apartment and OfficeBuilding. As the application evolves, much of the internal class structure is duplicated in ApplicationBuilder, which starts to look like a so-called “God Object”. Even if you split up ApplicationBuilder, implementation details for the constructed classes get spread around and the results can get pretty messy.

@al
is this your theory or actual experience? My expereince, especialy when using DI frameworks is that the code becomes much cleaner. Yes it is slightly more typing but the result is well worth it. Especialy from the maintainabilitypoint of view.

This is really based on experience, particularly with code that lasts several years (and therefore becomes a cash cow). It’s not just a matter of typing; it’s a question of encapsulation. And I see it as a conflict between a view unit testing and good object-oriented design.

For example, I may want to come out with a new, low-cost kind of house without a kitchen. I may want a new version of my app where the kitchen is optional, and is not created until the use clicks the “add kitchen” button and chooses the color. Or I may want to implement a new kind of kitchen and allow application logic to choose which one. These cases are examples of business rules, and really belong in the House class.

Unit testing and good OO go hand in hand, not against each other. My code has greatly improved once I have started test first development. Dependency injection helps even more with that. So in your case of wanting different kinds of kitchens you would have a house builder which would be responsible for creating the right kitchen and than injecting it into the house. A lot of people put the responsibility of making a kitchen into the house, but have you ever seen a house which con build a kitchen, but I have seen a lot of house builders (aka sub-contractors) which know how to come in and build me one.

True, but it would be inefficient and risky for the general contractor to buy all the construction materials he deems necessary and then inject them into the sub contractor’s shop.

As a practical matter, the sub contractor knows exactly what components are needed, and has much more knowledge of how they fit together. The general contractor has enough to worry about without delving into the implementation details of how the sink and faucet fit together.

If the plumbing regulations change and a different type of pipe is required, only the plumber has to modify his methods. The general contractor does not experience a disruption, does not have to learn new methods, and does not have to change the way he works.

Al: that’s true, so if the little nitpicky details of building a House adds up to grow too complex, the creation logic (logic of the HouseBuilder, which is separated from the logic of the House) can also be refactored into multiple objects, so you can have a GeneralHouseBuilder who delegates to a Plumber, so I see no real problems here. And then GeneralHouseBuilder will have a dependency, but we can apply DI to the GeneralHouseBuilder. By the time we get there, we can happily rename it to HouseConstructionShop. It can have a Plumber, an Electrician, and all the other subcontructors injected. But at this level the metaphor is starting to get out of touch, so we should just leave it alone now.

Another great article among many from you, Misko. I’m wondering what you would suggest when building an object graph that includes dependencies on 3rd party libraries that do themselves mix application logic with object creation.

For instance:

private LocalDevice localDevice;

public BluetoothManager() throws BluetoothStateException {

localDevice = LocalDevice.getLocalDevice();

}

Given that LocalDevice is not within my domain and .getLocalDevice() contains logic along with creation of a LocalDevice object, what would you do? Inject it into my BluetoothManager and introduce logic into my object graph builder, or perhaps move localDevice = LocalDevice.getLocalDevice() to an init() method and agree to suffer creating a LocalDevice from within my business logic?

But, you know, sometimes it just doesn’t make sense to test a house with stubbed kitchen. Let’s say that we have only one, absolutely perfect (“final class”) kitchen. Then there’s no need for DI and builders, kitchen is integral part of the house, and both the house and the kitchen should be treated like a black-box, single entity…

sure, if you are certain that they will always come together, than sure you can do that, but you will never be able to wire it differently. You can get away in few leafs sometimes with this strategy, but it should be rare, the default behavior should always me inject, unless you have a really good reason why it should be something different.

[...] 9. Unit testing: OCUnit and OCMock are fairly immature compared to jUnit and jMock. And furthermore, a number of Cocoa classes include real work in their “constructors.” For instance, NSUrlConnection actually opens an HTTP connection and interacts online in its initWithRequest:delegate: method. The problem this creates is that object creation is tied to real work. This makes dependency injection difficult because we can’t separate the creation of the object from the logic, which would be required in order to substitute a test stub with test logic in its place. Dang. For more on this, see Misko Hevery’s great article on unit testing, object creation and logic. [...]

this class can be created with empty constructor, which can be very handy in many situations, and it will be decrease count of not necessary initializations of Kitchen object in code.
In other hand, this object can be created with special version of Kitchen (e.g. mock-object) in tests.

What you have suggested at first looks like a good idea, and as long as you look at the class in isolation it is. The trouble becomes when you are testing house which needs kitchen. Since house will call the default constructor it is easy to cross the line and have the whole thing become the same as not having DI, so in practice this dose not work.

just read all the blogposts about this topic. Great stuff, I really liked those and I hope I remember to send them to my friends!

I have a question though, do you believe, that the separation of Object Construction and Logic should even be valid for standard library Objects such as Collections? If I need a queue for storing incoming Messages, would it be a violation to your rules to write
messageQueue = new Queue( );
inside the Constructor of my Class?

I would really like to hear your opinion on that. I suspect, that it is the best way to handle this, because the Queue (or any other Standard Library Object) is completly tied to my Class, even when Unit Testing.

I have been scratching my head and searching the web trying to understand where ‘new’ fits inside the object graph and now I finally get it. Thank you so much for this very well written, easy to understand article.

I have one question though. How will you unit-test you Main class ? (Maybe you would say that you don’t unit-test a Main class, but in this case what if you call your “new ApplicationBuilder().build()” in another class that you habe to unit test ?)

Would you use a DI framework to inject the builder to the classes that need it ?

Thanks for all your articles ! All those subjects about testing are really interesting, unfortunately industry seems not to care that much about them.