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

July 8th, 2008 · 44 Comments ·

By Miško Hevery

  • 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…

class House {
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    isLocked = true;
  }
}

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.

class House {
  private final Kitchen kitchen = new Kitchen();
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

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 real House with a fake Kitchen so that we can unit-test the House in isolation.

class House {
  private final Kitchen kitchen;
  private boolean isLocked;

   public House(Kitchen kitchen) {
    this.kitchen = kitchen;
  }

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

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.

class ApplicationBuilder {
  House build() {
    return new House(new Kitchen(
               new Sink(),
               new Dishwasher(),
               new Refrigerator())
           );
  }
}

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.

Tags: Testability

44 responses so far ↓

  • How to Write 3v1L, Untestable Code | Miško Hevery // Jul 25, 2008 at 1:28 pm

    [...] Cover your ears when some testing weenie tells you about Dependency Injection, Law of Demeter, or not looking for [...]

  • Silvan Mühlemann // Aug 7, 2008 at 11:44 pm

    Nice article. A few surprisingly good concepts:
    - Summary in the beginning
    - using a “House” and a “Kitchen” instead of “foo” and “bar”
    - looking at an application as a graph with nodes an leafs.

  • Where Have All the Singletons Gone? | Miško Hevery // Aug 21, 2008 at 11:50 am

    [...] 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 [...]

  • Jon Lebensold » Blog Archive » What is Dependency Injection? Go Ask a Java Nerd! // Aug 30, 2008 at 3:32 am

    [...] 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 [...]

  • Where Have all the “new” Operators Gone | Miško Hevery // Sep 10, 2008 at 10:25 am

    [...] of running the application. The reason that this separation is important was outlined in How to Think About the “new” Operator. So let us look at where have all of the new operators [...]

  • Application Wiring on Auto-Pilot | Miško Hevery // Sep 24, 2008 at 10:35 am

    [...] talked about how it is important to separate the new operators from the application logic. This separation forces your code to have factories which are responsible for wiring your [...]

  • Singleton I love you, but you're bringing me down | // Coding Without Comments // Oct 9, 2008 at 4:27 am

    [...] 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 [...]

  • Dependency Injection Myth: Reference Passing | Miško Hevery // Oct 22, 2008 at 7:57 am

    [...] 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. [...]

  • dholm.com » Blog Archive » Tumblelog: 081117 // Nov 17, 2008 at 12:07 am

    [...] How to Think About the “new” Operator with Respect to Unit Testing is an excellent introduction to dependency injection and why you need it. Also read How to Write 3v1L, Untestable Code. [...]

  • Viktor Nordling // Nov 27, 2008 at 2:24 am

    First of all, I really like your articles and the videos as well. I am learning a lot.

    Now, just to be silly. I think you have not unit-tested your main method very well in the above example:

    public static void(String…args) {

    should probably be:
    public static void main(String…args) {

    ;)

    Keep up the good work!

  • Static Methods are Death to Testability // Dec 15, 2008 at 10:50 am

    [...] method, one would have to instantiate the object first, and that may prove to be a problem. (See how to think about the new operator, and class does real [...]

  • gropapa // Dec 15, 2008 at 3:21 pm

    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)

  • Interfacing with hard-to-test third-party code // Jan 4, 2009 at 12:28 pm

    [...] Servlets require a no argument constructor which prevents us from using dependency injection. See how to think about the new operator. [...]

  • Tetsuo // Jan 6, 2009 at 6:35 am

    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.

  • misko // Jan 6, 2009 at 9:38 am

    @Tetsuo

    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.

  • Rogério // Jan 7, 2009 at 3:16 pm

    “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?

  • Jonathan Hartley // Jan 13, 2009 at 4:30 pm

    Hi.

    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.

    Best regards,

    Jonathan

  • misko // Jan 13, 2009 at 9:26 pm

    @Jonathan,

    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.

    – Misko

  • When to use Dependency Injection // Jan 14, 2009 at 11:38 am

    [...] answer to this question should be a resounding yes! We covered this many times how to think about the new-operator, singletons are liars, and of course the talk on [...]

  • Jonathan Hartley // Jan 15, 2009 at 1:31 am

    Hi.

    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.

  • misko // Jan 15, 2009 at 7:56 am

    @Jonathan,

    Why can’t you ask the factory to build a small maze and assert that the maze is correctly built?

    – Misko

  • Graeme // Jan 21, 2009 at 6:11 am

    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.

  • How to do Everything Wrong with Servlets // Apr 8, 2009 at 11:43 am

    [...] means it is loaded with new operators, and those suck from the testability point of view. (see here) Now I really want to test the home page but the home page servlet inherits from the [...]

  • Hydrocon Session Log, 1241655767 « I Built His Cage // May 6, 2009 at 5:23 pm

    [...] 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. [...]

  • Al // Jul 9, 2009 at 1:34 pm

    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.

  • misko // Jul 10, 2009 at 6:53 am

    @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.

  • Al // Aug 25, 2009 at 6:08 pm

    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.

  • misko // Aug 26, 2009 at 12:54 am

    @Al,

    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.

  • Al // Aug 28, 2009 at 6:43 pm

    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.

  • fqqdk // Aug 29, 2009 at 1:15 am

    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. :D But at this level the metaphor is starting to get out of touch, so we should just leave it alone now. :)

  • Richard Rauser // Sep 17, 2009 at 8:11 am

    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?

  • Radek // Sep 18, 2009 at 8:41 am

    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…

  • misko // Sep 18, 2009 at 8:53 am

    @Radek,

    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.

  • Dependency Injection and Inversion of Control | Geek on the Loose // Feb 20, 2010 at 5:50 pm

    [...] Fowler: Inversion of Control Containers and the Dependency Injection pattern [5] Miško Hevery: How to Think About the "new" Operator with Respect to Unit Testing [6] Top 50 Linux Quotes of All Time, #10 [note lkml == Linux Kernel Mailing List] [7] Miško [...]

  • Objective-C: Frustrations of a Java Programmer | richardrauser.com // Jul 7, 2010 at 11:08 am

    [...] 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. [...]

  • OZ // Apr 26, 2011 at 6:31 am

    First: Thank you for your lessons, I become understand much more.

    I agree, that DI is much more flexible way, but anything has it’s cost, and cost of using DI is lot of passed arguments.

    What if we will build class both flexible (able to be isolated) and self-enough?
    My example will be in PHP, not Java, excuse me for this, but I hope syntax not so different:

    class House
    {
    private $kitchen;

    public function __construct(IKitchen $Kitchen = null)
    {
    if (empty($Kitchen)) $Kitchen = new BaseKitchen();
    else $this->kitchen = $Kitchen;
    }
    }

    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.

    Please, comment, what do you think about this variant.

  • misko // May 5, 2011 at 9:20 am

    @Oz,

    The cost of DI is arguments is a myth of not taking DI to its extreme: http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing/

    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.

  • Morl99 // May 31, 2011 at 5:54 am

    @misko

    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.

    Keep it up!

  • misko // Jun 5, 2011 at 11:24 am

    @Morl99,

    No, value objects do not need to be separate their news. More discussion here: http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

  • Asbjørn // Sep 7, 2011 at 5:45 am

    How about using a mock/stub tool that doesn’t require DI?

  • Ben // Apr 9, 2012 at 6:59 am

    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.

  • Ruby (programming language): What Ruby conventions explicitly avoid mixing object graph construction & application logic? - Quora // Jul 21, 2012 at 12:58 pm

    [...] mixing object graph construction & application logic?I've been reading Miško Hevery — http://misko.hevery.com/2008/07/…Post   Add AnswerBIU     @      [...]

  • Romain // Dec 19, 2012 at 10:44 am

    Hi,

    Thank you for this article, it is really great.

    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.

    Romain.

  • Brian // May 1, 2013 at 4:31 pm

    If you aren’t using a dependency injection pattern and have already successfully tested all the leafs of a branch, are you not safe to test the branch despite it not being in isolation?

Leave a Comment