Is using dependency injection (DI) essential for unit testing?

I can't think of another alternative for isolating code so it can be tested. Also, all the examples I have ever seen use this pattern. Is that because it is the only viable option or are there other alternatives?

  • 5
    Dependency Injection is not essential, but the broader concept of Inversion of Control is.
    – Jeremy
    Mar 22, 2012 at 15:56
  • There is something to be said for the scale here. If I have a small code base with very few layers then DI may not be useful.
    – JB King
    Mar 22, 2012 at 18:44
  • @JBKing if you have a small code base you don't need layers or unit testing
    – Sklivvz
    Jan 31, 2014 at 20:43
  • 2
    Lots of design decisions are necessary to make your code testable. Start writing tests and find out. Aug 2, 2016 at 0:31

7 Answers 7


DI makes unit testing much easier. But you can still write unit tests without DI. Lots of unit tests have been written already before DI became widespread. (Of course, some of these used techniques identical or very similar to DI without knowing it has a fancy name :-)

I myself have used e.g. interfaces and factories a lot before learning about DI. The actual factory class name may have been read from a config file, or passed to the SUT as an argument.

Another approach is using singletons (or globally accessible data in general). Yes, I know it is not recommended by many (including myself) in general. Still it may be viable in specific situations, especially if the singleton contains static configuration data which is not test case specific, but differs between production and test environment. Of course it has its known problems, so DI is superior if you can use it. But often (e.g. in legacy systems) you can't.

Talking of which, Working Effectively With Legacy Code describes a lot of tricks to get legacy code covered by tests. Many of these are not nice, and aren't meant as a long term solution. But they allow you to create the first valuable unit tests to an otherwise untestable system... which enables you to start refactoring, and eventually (among others) introduce DI.

  • Agreed, DI is particularly usefull for mocking objects. But there are many scenarios where DI is useless in tests.
    – Kemoda
    Mar 22, 2012 at 15:42
  • @Kemoda like for example what? Mar 22, 2012 at 15:43
  • @VJovic For example standalone objects. I think of a method that takes some arguments and performs some stuff but does not depend on another component (thus no need for DI).
    – Kemoda
    Mar 22, 2012 at 15:52
  • @Kemoda It sounds like you're describing functional programming, and you are using DI. You're injecting your dependencies as method parameters. Mar 22, 2012 at 16:05
  • 3
    @huggie, why would implementation details get leaked here? The dependency injected is typically hidden behind an interface, and the whole point is that the client class has no idea of - and is not concerned with - whether the actual implementation of this dependency is a real production class or a mock. Its instantiation happens outside the client class, it only gets to see the ready-made instance. Dec 28, 2013 at 17:47

Decoupling is essential for unit testing. DI is a great way to achieve decoupling.

  • 27
    A very true statement that in no way answers the question.
    – Travis
    Apr 20, 2014 at 15:14

Depending on the technologies that you're using, you can isolate dependencies without using DI. For instance, in the .NET world, Moles allows you to isolate dependencies without the DI pattern.

That said, I believe these isolation frameworks are written and intended for situations in your code with external dependencies (filesystem, database, etc). That is, the fact that one can do this doesn't mean he or she should.

Dependency injection allows unit testing, but it also allow modification of an object's behavior without altering the code of that object (open/closed principle). So, it isn't just testable code, but flexible code that results. I've generally found that there is a heavy correlation between maintainable/flexible code and testable code.

  • 3
    Or Moles lets you think you've got clean, well factored testable code because you are testing through magic. Mar 22, 2012 at 15:55
  • @WyattBarnett Yeah, very true. Moles has a wince-inducing ability to get someone to say "who needs all of this polymorphism and open/closed stuff, anyway?!?" Mar 22, 2012 at 16:07
  • 1
    Moles was replaced by fakes, and from the fakes page "The Fakes framework helps developers create, maintain, and inject dummy implementations in their unit tests" Sounds like DI to me.
    – Sign
    Mar 22, 2012 at 17:00
  • 1
    @Sign Your link also says, "The Fakes framework can be used to shim any .NET method, including non-virtual and static methods in sealed types.". The fact that the isolation frameworks can be used in conjunction with DI doesn't mean that they are DI. Mar 22, 2012 at 18:40
  • Dependency injection is not essential for unit testing

  • Inversion of control on other hand is essential when you want to swap one implementation for another.


No, DI is not essential for unit testing, but it helps a lot.

You can use factories or locators and test as you would with DI (just not as elegant and would require more setup).

Also, Mock Objects would be important in legacy systems where many calls are delegated to functions instead of dependencies. (Mock Objects can also be extensively utilized in a proper setup as well)

There can be setups where testing is nearly impossible. But this is not based on whether or not dependency injection is used.


No, dependency injection is not essential for unit testing.

Dependency injection helps if you have a class that needs a dependent class-instance to do some sub-processing. Instead of DI you can seperate the logic of a business-method into a data-gethering-part (that is not unit-testable) and a calculation part that can be unit-tested.

Example (using DI) This implementation depends on Employee, Account, ...

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
     if (amount > 100 && employee.isStudent())
        return false;
     if (to.getOwner().getFamiliyName() == employee.getFamilyName() && ...
        return false; // cannot transfer money to himself;

After seperation of data-gathering and calculation:

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
     return hasPermissionToTransferMoney(employee.isStudent(), employee.getFamilyName(), to.getOwner().getFamilyName(), ...);

 // the actual permission calculation
 static bool hasPermissionToTransferMoney(boolean isStudent, string employeeFamilyName, string receiverFamilyName, ...)
     if (amount > 100 && isStudent)
        return false;
     if (receiverFamilyName == employeeFamiliyName && ...
        return false; // cannot transfer money to himself

The calculation part can be easily tested without dependency injection.


Yes, there are alternatives to the use of DI for isolation.

One alternative is to use factories or a ServiceLocator which can be configured from tests to return mock objects instead of real ones.

Another is to use a suitable isolation framework or mocking tool. Such tools exist for just about every modern programming language (for Java, C#, Ruby, and Python, at least). They can isolate a class being tested from the implementation of other classes/types, even when the tested class directly instantiates its dependencies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.