views:

95

answers:

3

From my initial readings on unit testing (I'm a beginner) it is wise to put all of your setups and tests in a separate project from the code being tested. This seems ideal to me, as well. However, I've recently begun reading The Art of Unit Testing, trying to discover how to break dependencies on things such as database calls. The methods offered involve changing areas of the test code, such as adding specific interfaces and "stub" methods to the production code. This seems to defeat some of the good things about keeping tests and production code separate.

Is there any recommended dependency-breaking technique that doesn't involve changing production code?

+4  A: 

There is no way to break dependencies without making some sort of change. What is important is that the changes you make don't change the behavior of production code in production, and that you aren't introducing worse dependencies.

Kristopher Johnson
+3  A: 

By definition, the dependencies need to be broken in the production code to make it more testable, i.e., to make the production code more testable you need to change the code to make it less coupled to actual implementations. This will allow you to substitute mock objects for the real objects in the class under test in your tests. This removes the dependency on other production classes that the class under test depends on.

If you've written loosely-coupled production code -- code that relies on interfaces rather than implementations, that uses factories and dependency injection to create objects rather than direct instantiation -- then you may only need to make small changes or none at all to your production code. If not, then you will need to make those types of changes. This isn't a bad thing, however, as it will improve your design by reducing coupling between classes. The cost of this will be a few extra (small) classes and/or interfaces that make the isolation possible.

If you use TDD (Test Driven Development/Design), the types of construction that you use in your production code will change to make it more naturally testable. This is one of the ways that TDD works to improve design as well as incorporate testing into your code.

Note that you shouldn't need to introduce coupling or dependencies in your production code to your test code. Your test code will obviously be dependent on production and you may need to refactor the dependencies in production to make it more testable, but if your production code "knows" anything about how it's being tested, you've probably done something wrong. You've probably introduced artificial interfaces when you should be using dependency injection.

tvanfosson
A: 

We use Spring along with factories to break dependencies. With Spring's dependency injection, changing from development and testing, to production is just a different XML file.

Bill