Design Tech Talk Series Presents: OO Design for Testability
Why Stack Overflow recommends it
Stack Overflow users link it when explaining why constructors should not do work, why singletons and static state are bad, and how dependency injection makes mocking possible.
Recommended by 11 people across 13 different months, 2009 to 2024.
What it is
A 2009 Google Tech Talk by Miško Hevery on designing object-oriented code so it can be tested easily. It covers dependency injection, why singletons and global state hurt testing, and why doing real work in constructors makes classes hard to test.
What people said
Strong rec Bozho · 2010-09 · Stack Overflow · on “Where can I investigate junit tests in a real world project?”
Any serious project (including open source) has unit tests. For what I've seen spring and hibernate have a lot of them. This [this video] is a very good lecture about Object-oriented design for testability. It is not for complete beginners, but it gives very good insights.
Strong rec Franz Becker · 2015-06 · Stack Overflow · on “Java Object creation pattern and design”
Your underlying point is perfectly valid, it's usually not a good idea to instantiate objects directly in the constructor (they may be valid exceptions from that rule). If you do this: class Car { private Engine engine; public Car() { engine = new Engine(); } } You will have a hard time testing the Car without the engine. You'll have to use reflection in order to exchange the instance by a mock. If you do the following instead class Car { private Engine engine; @Inject public Car(Engine engine) { this.engine = engine; } } it is very easy to test the Car with a fake engine, replace the implementation of engine or change the way the engine should be constructed (e.g. add more parameters to the
Recommends Bozho · 2010-02 · Stack Overflow · on “Mock Runtime.getRuntime()?”
Your class shouldn't call Runtime.getRuntime() . it should expect a Runtime to be set as its dependency, and work with it. Then in your test you can easily provide a mock and set it as a dependency. As a sidenote, I'd suggest watching this lecture on OO Design for testability [this video] . Update: I didn't see the private constructor. You can try using java bytecode instrumentation [LINK] in order to add another constructor or make the constructor public, but that might turn out to be impossible as well (if there are some restrictions on that class). So your option is to make a wrapper (as you suggested in the question), and follow the dependency-injection approach.
Recommends Bozho · 2010-02 · Stack Overflow · on “mocking a singleton class”
It very much depends on the singleton implementation. But it mostly because it has a private constructor and hence you can't extend it. But you have the following option make an interface - SingletonInterface make your singleton class implement that interface let Singleton.getInstance() return SingletonInterface provide a mock implementation of SingletonInterface in your tests set it in the private static field on Singleton using reflection. But you'd better avoid singletons (which represent a global state). This lecture [this video] explains some important design concepts from testability point of view.
Recommends bitc · 2010-03 · Stack Overflow · on “Program Structure Design Tools? (Top Down Design)”
Two-part answer The methodology of Divide and conquer [LINK] is pretty straight-forward: Think of the algorithm in the most abstract sense. What needs to be done? Break down the problem into sub-problems. And do this recursively until these become simple enough to be solved directly. To keep things tidy. Let one function/method only have one purpose. A long and complex function is a pretty good indication that you need to break it down further. Refactoring then becomes the process of finding and removing duplicated code. If you have not had any experience with functional programming yet, you should at least try it out for the learning experience. You will come to find that this way of thinki
Recommends Bozho · 2010-04 · Stack Overflow · on “Dependency Injection & Singleton Design pattern”
If you want to verify what gets logged in a test, you need dependency injection. Furthermore, a logger is rarely a singleton - generally you have a logger per each of your class. Watch this presentation [this video] on Object-oriented design for testability and you'll see why singletons are bad. The problem with singletons is that they represent a global state which is hard to predict, especially in tests. Have in mind that an object can be de-facto singleton but still be obtained via dependency-injection, rather than via Singleton.getInstance() . I'm just listing some important points made by Misko Hevery in his presentation. After watching it you will gain full perspective on why it is better t
Recommends Bozho · 2010-09 · Stack Overflow · on “Any problem with doing the main work of a class in its constructor?”
The main practical problem is unit-testing - you won't be able to instantiate the object without doing actual work. (Or you'd have to mock all the classes that participate in this work). Related talk: OO Design for testability [this video] . It gives examples of why doing work in constructors is bad for unit-testing.
Recommends Michel Löhr · 2011-01 · Stack Overflow · on “Programming Workflow with Unit Testing but Without TDD”
PS on unit-tests, one need to learn how to write tests and therefore how to write good testable code. A good google series presentation can be found here: [this video]
Recommends Andrey Adamovich · 2011-06 · Stack Overflow · on “Integration Test for JUnit”
There is plenty of material on the internet about design for testability. For example, you can watch this presentation: [this video]
Recommends User · 2011-07 · Stack Overflow · on “How to safely unit-test write operations in Symfony 2?”
I agree with Mitch. I would add that you should decide whether you want to do an integration test or a unit test (or both, but not in the same test). If, in fact, you do want to do a unit test, realize: Your code has a "dependency" on an external database. When unit testing you'll have to find a way to "fake" the database. You want to test a "unit" which means a single thing, not two or more things (i.e. your CRUD code AND your connection to a database AND the database itself). Typically you'll need to refactor your code using something like dependency injection so that when unit testing you can fake things that your code depends on. Unit testing isn't just testing your code. That's actually