Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I learned to do Test Driven Development (TDD), Dependency Injection (DI) and Inversion of Control (IoC) all at the same time. When I write code using TDD I always end up using DI in my class's constructors. I am wondering if this is because of how I learned to do TDD, or if this is a natural side-effect of TDD.

So my question is this: Does following TDD principals and writing unit tests that do not depend on external services inevitably lead to DI?

share|improve this question
4  
I'm reading The Art of Unit Testing and and it seems that it definitely does lead to Dependency Injection (DI). –  Jason Holland Aug 15 '12 at 15:07
2  
So what language is this about? DI/etc are necessary in Java, but that's because of a language limitation - languages like Python don't need it since they can monkey patch dependencies in the tests. –  Izkata Aug 15 '12 at 19:26
    
@Izkata: I agree that DI is a workaround for a language limitation; but monkeypatching isn't necesarily the same thing in less rigid languages. Among other ways I'd prefer first-class functions, which allows you to do naturally what DI approximates by discipline. –  Javier Aug 15 '12 at 22:39

5 Answers 5

up vote 17 down vote accepted

Does following TDD and writing unit tests that do not depend on databases or external services inevitably lead to DI?

For wide definitions of DI, yes. Classes do not exist in a vaccuum, so they need to have their dependencies filled somehow. Sometimes just providing a value is fine. Sometimes you need to provide a mock in the constructor. Sometimes via IoC containers. Sometimes via private test accessor. It's all injecting some test thing into the class so it can work in isolation.

share|improve this answer

Yes and no: TDD leads to writing well-structured code, which itself leads to DI.

By that I mean TDD generally sends you the right way with regards to encapsulation, SRP and reusability. It's not just about getting some tests round your code: it's about using those tests to flesh out a better design. If an object creates its own dependencies, then it's living within a specific context within a specific application and is likely to be woven into the application to a greater degree. DI is a good thing, not just from a testing point of view, but also from a code quality point of view.

share|improve this answer
    
Could you clarify the no part of your yes and no answer? How does one do TDD without DI. –  Gilles Aug 15 '12 at 16:13
    
The 'no' part being I don't think it's a direct link between TDD and DI. It's indirect via code quality. Which is splitting hairs probably, but just thought I'd point out that code quality is the thing you're aiming for, not just testability. –  Tim Aug 15 '12 at 16:15

For people who already know about DI, but just have never seen the point, I think unit testing will almost invariably lead to using DI.

If you don't know about DI and are trying to write unit tests, some people will naturally reinvent DI, some will get frustrated and eventually discover DI through research, but you'd be surprised how often it simply won't occur to someone that there might be a better way to architect their software to make unit testing easier. Those people write off unit testing as intractable and give up.

share|improve this answer

Unit testing will lead to DI (since it forces you to create loosely coupled units). TDD not necessarily, since TDD can also be used for creating tests layer-by-layer, instead of "verbatim" unit tests. See this article

http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

for an explanation of the differences.

share|improve this answer
1  
+1 for "TDD is not UT". Also for recognizing that the extreme uncoupling is a common result of UT, not (necessarily) of TDD. –  Javier Aug 15 '12 at 22:41

As already pointed out in other answers, TDD does not require unit tests. You can just as well write integration/functional tests while doing TDD. Of the several ways to apply TDD, creation of unit tests would be the "fake it till you make it" way (see the book by Kent Beck for details).

As for "TDD inevitably leads to DI", it definitely does not. What one needs when writing unit tests is to isolate the unit being tested from the implementations of its external dependencies. And this can be done just as easily with or without DI. The best way, probably, is to use a proper isolation/mocking tool.

share|improve this answer
    
But to use mocks mustn't you necessarily inject the dependencies in the class? –  Gilles Feb 1 at 1:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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