Hi guys, it’s been a while that I haven’t posted anything. I was thinking writing all those technical things sometimes is not enough for the reader to visualize the concept. So I came up with a screencast this time. I’ll try to create these screencasts once a week and will cover different topics. This series will contain Making Code More Testable talks only. For other topics, I’ll create different series. Anyways, let’s get back to the overview :)
In this first screencast I’ll try to cover how you guys could break the static dependencies in your constructor. Let me give you some brief overview about these dependencies:
Dependencies
Dependencies are everywhere in our little world. Every unit, every module is depending on something. Sometimes it’s another unit, sometimes it’s another modules, and sometimes it’s another library. And there are lots of discussions currently going on to make your units, modules more scalable and more isolated! All OSGi, maven, DI (Dependency Injection) and SOLID principles are just for this purpose. To help you to break/isolate/modulate your code base.
In this screencast I’m gonna talk about only a single part of whole this picture. Static dependencies within your constructors.
Static Dependencies Within Constructors
This type of dependencies are very evil when it comes to do unit testing. It could turn into a very big puzzle game sometimes. The basic idea is some developers tend to place their dependent services or non-value objects into the constructor and using singleton and/or static methods. Without being aware of what they’re doing, they sometimes even place if/else, try/catch, switch/default statements into this tiny part of the code.
So how it happens? Very easy, let’s consider the following code snippets:
/** My class. */
public class MyClass {
private Service service;
/** Default constructor */
public MyClass() {
// lots of logic that shouldn't be here..
// and
this.service = Service.getInstance();
TimeService.recordTime();
}
}
(EDIT) As you may clearly see, it’s very hard to test this unit since it has non-injectable static dependencies. So what do we need to do?
There are couple ways to break these dependencies. Before going into too deep, I want to clarify something here. “DON’T EVER DO THIS”! When you write your code, maybe you don’t follow TDD or anything. But please consider there will be some people that have to deal with this code after you. Then again, if you’re selfish.. There is no more word to say!
Breaking the Dependencies
As I said, there are couple ways to break these sort of dependencies.
Constructor Delegation
First and my favourite is Constructor Delegation. The basic idea for this technique is create another constructor which takes these dependencies for dependency injection and delegate the first constructor to the second one. Please consider following code’s before/after and usage scenarios:
// BEFORE 'constructor delegation'
public class LibraryManager {
private LibraryService service;
public LibraryManager() {
this.service = LibraryService.getInstance();
}
// more code
}
// AFTER 'constructor delegation'
public class LibraryManager {
private LibraryService service;
public LibraryManager() {
// delegate to the new constructor
this(LibraryService.getInstance());
}
// new constructor
public LibraryManager(LibraryService service) {
this.service = service;
}
// more code
}
// USAGE 'in the test'
LibraryManager manager = new LibraryManager(mockLibraryService);
// ...
// do your assertions
Endo Testing
Second technique is from Endo Testing. The technique here is extracting these dependencies to getter equivalents and overriding these methods for returning the mock/stub/fake ones. One thing here is your getter methods should be package private or protected. Please look at the following before/after and usage scenarios again:
// BEFORE 'endo testing'
public class SmartHitter {
private Exchange exchange;
public SmartHitter() {
this.exchange = Exchange.getActiveExchange();
}
// more code
}
// AFTER 'endo testing'
public class SmartHitter {
private Exchange exchange;
public SmartHitter() {
this.exchange = getActiveExchange();
}
protected Exchange getActiveExchange() {
return Exchange.getActiveExchange();
}
// more code
}
// USAGE 'in the test'
final Exchange mockExchange = mock(Exchange.class);
SmartHitter hitter = new SmartHitter() {
@Override
protected Exchange getActiveExchange() {
return mockExchange;
}
};
// ...
// do your assertions
Setter Injection
The last one is not applicable to all scenarios, but it’s another dependency injection mechanism (@see Dependency Injection). For this one, you basically create a setter method for your dependency and allow test to inject this dependency. Let’s look at the example:
// BEFORE 'setter injection'
public class AjaxPriceModifier {
private CatalogService catalogService;
public AjaxPriceModifier() {
// initialization..
this.catalogService = CatalogService(sessionHelper.getStore());
}
// more code
}
// AFTER 'setter injection'
public class AjaxPriceModifier {
private CatalogService catalogService;
public AjaxPriceModifier() {
// initialization..
this.catalogService = CatalogService(sessionHelper.getStore());
}
public void setCatalogService(CatalogService catalogService) {
this.catalogService = catalogService;
}
// more code
}
// USAGE 'in the test'
AjaxPriceModifier modifier = new AjaxPriceModifier();
modifier.setCatalogService(mockCatalogService);
// ...
// do your assertions
As you may notice, without a getter of that dependency your code still has the dependencies. It’s very wise to place a getter for that dependency and use that getter (as in Endo Testing) method in the constructor.
Summary
My personal favourite is Constructor Injection since it’s more intuitive when you’re coding the test. It clearly describes what dependencies you need to test that unit. Okay, now you can watch the screencast. Hope it turns some lights on :) All comments are welcome!










Very cool screencast, learned a lot. Keep up the good work.
August 31, 2009, 11:34 AMNotice that this article relies on a critical assumption: that there are Java code constructs which are “not testable” (meaning that their use would prevent the isolation of a unit from its dependencies, in the context of a unit test).
It turns out this assumption is false. The JVM really has some amazing abilities, which have been exposed in easy to use mocking APIs by certain open source tools.
Today it’s safe to say that, in the context of unit testing Java code, there is no such thing as “untestable code”.
August 31, 2009, 11:41 AM@eugen 10x,
@rogerio, problem is not about can/cannot test the code. It’s ‘how easy‘ to test the code. The assumption is generally declared like that to actually describe this situation. Just think like this, if your constructor or any of your method does amazing job in its implementation by keeping all in-method dependencies, maybe a developer could do some testing using his/her advanced knowledge. However do you think is this really required to do a simple unit testing? Or is there a major need to make your code this much complicated? To me there are couple issues here. First it makes harder for the next developer to adapt the code! Second it’s very hard to maintain ‘coz lots of things have in-method dependencies. And third it increases the risk of potential problems. And last but not least is code like this is hard to read/understand. I see your point, but you can’t expect every developer in your team to be as knowledgeable as you’re. Hope we’re on the same page here..
August 31, 2009, 1:28 PMWell, you specifically wrote “there is no way for us to test this unit”, concerning “MyClass”. So it seems to me that it is indeed about the possibility or impossibility of unit testing the code.
How easy it is to unit test a piece should only depend on its intrinsic complexity, not on accidental characteristics. For example, it should not matter if the code makes use of constructors, final classes/methods, static methods, or whatever. These are all perfectly valid Java language features and idioms.
The problem with using DI (or any other principle or pattern) for the sake of unit testing is that it will tend to make the code more complex, often with pointless interfaces/abstractions, “setter methods”, “wiring configuration”, etc. that only add noise to the codebase.
Clean, short and elegant unit tests can be written for any production code, depending only on the essential complexity of the tested code. DI really only adds complexity, not reduces it.
Doing this in real-world projects has nothing to do with how knowledgeable a developer is. The developers will need to learn the mocking API, that’s all. Compare that to learning Guice or Spring IOC.
August 31, 2009, 2:32 PMI think I should fix that sentence. Apparently it’s misleading:)
About your concerns with DI vs in-method dependencies, both side has its own advantages and disadvantages. We can’t put a silver bullet rule for all conditions. My experience with DI tells me good things rather than its complexity. However I agree that if you’re using Spring sort of frameworks you might end up having lots of interfaces or setter methods which you’ll never need. I already mentioned this problem in one of my previous article (@see Naming Java Implementation Classes). Then again to me creating a nice dependency mechanism makes code much more readable and easy to understand. The quantity of your java classes or methods doesn’t matter, I think having clean code is very important. And without DI or principles/patterns, people feel themselves so free and goes into procedural programming rather than OOP. And following these sort of principles/patterns keeps the conventions. When you see a code that uses these conventions, it’s really not hard to adapt it. But as I said, both usages have their own benefits. I can’t argue about it although I feel myself more comfortable in the DI side.
August 31, 2009, 3:36 PMI really try to keep an open mind about DI, but I always seem to get frustated with what I find. If you read the Guice or Spring IOC documentation, for example, there is hardly any logical argumentation or examples about the value of DI, apart from the outdated talk about unit testing (which really only reflects the limitations of certain other mocking tools).
I would like to find a good text that explains how DI helps make code more modular or maintainable. What I have seen so far leads me to believe that DI often is detrimental to OO design.
Specifically, developers tend to make service classes stateless instead of stateful, so they can be singletons. This is not good design. I prefer to favor stateful service classes, with instance lifetimes limited to the business operations that rely on them. Such instances are typically created with context-specific data, usually coming from the UI. Using DI would prevent me from doing this. Also, DI requires dependencies that would otherwise be private to be publicy exposed; this violates the information hiding principle. And lets not forget about the KISS and YAGNI principles.
A good example of DI abuse is the DDD sample application. It can be simplified a lot, without any obvious loss in design qualities. I actually intend to create a JMockit-based version of it when I get the time, as another sample for the toolkit.
August 31, 2009, 4:56 PMNice demo, but please write your tests first! Lets not propogate bad habits.
Also for the other commenters, if you want more info on writing testable code, and why DI really helps then check out Misko Hevery’s Clean Code talks – http://misko.hevery.com/2008/11/04/clean-code-talks-unit-testing/
September 6, 2009, 3:47 AM@gavin 10x for the comment. Yeah that could have been done for the second part of the implementation. Then again it’s just a personal choice. I’m not in favour or writing tests first for delegator methods. As I said, personal choice. To me ‘Agile’ and ‘TDD’ have so vague concepts and everybody has an opinion about them. Some says ‘this has to be done this way’, some says ‘no actually the other way’. And if you look at the titles of those people you would be surprised why their comments don’t match:D Anyways, I believe in TED (Test Enhanced Development) rather than TFD (Test First Design). To me it sounds more logical. And think about it as long as you keep your units tested, we can’t say it’s a bad propagation right? Johannes Link and Peter Fröhlich has a nice chapter in ‘Unit Testing in Java’ (somewhere in the middle of the book) that covers these sort of topics. For those who can’t decide how much is enough, they can refer to that book.
And Misko is one of the heroes of this topic. I think there is not much of a guy like him that still insists on testable codes rather than unit testing :)
September 6, 2009, 5:02 PM