Browsed by
Tag: java

Experience: Introducing JMockit To The Team

Experience: Introducing JMockit To The Team

Like many codebases out there, our codebase at work had a backlog on unit & integration tests and it was high time we covered it up. So one fine day, it was decided that we shall no longer accept code without tests. Then the question of ‘how do we write tests’ came up. As one of the architects on the team I introduced the methodology of unit/integration testing and a mocking library (JMockit) to aid in cases where testing could be difficult without one, conducted trainings and hands-on sessions for everyone on the team, set up a peer review process and we were ready. That is all there is to the history of the situation we are in. Well, we are talking about a large team here, some eighty people working on a large codebase as a whole, although divided in multiple microservices.

Today, almost every test we have has a mocked class, and an expectation set on some dependency. Many tests verify how many times a particular internal/private method or a method on a dependency was invoked, some have VOs mocked, or have assertions on return values inside verifications block. A few have gone to the lengths of mocking constructors of certain objects because there was no way to inject them into tested class. We are not even considering the private and static method mocks here.

When I look at the tests that we have today, and look back on the last few months, I wonder if I made mistake while introducing the mocking tool. In the trainings we had, we discussed the purpose of a mocking tool, issues due to overuse, indicators of overuse; heck there was even slide dedicated to this in the developer induction we have here. Architects were involved in many code reviews and tried avoiding these pitfalls, but clearly it was not enough.

Tests are supposed to improve the design of the code. Since the highly tangled, coupled classes, classes breaking SRP (Single Responsibility Principle) are difficult to test, we tend to fix them. As the size of the class increases, the functionality it has grows making it difficult to test, so we split it. As the dependencies being created makes it difficult to test, we change the class to allow injecting them. We end up splitting large methods, redesigning methods with side effects, removing unneeded code, decoupling from the libraries all for making the code testable and effectively get cleaner, maintainable, verifiable code. All of this, only if we wrote tests correctly.

If we started modelling our tests to match our code, we not only lose all the benefits, but the tests start becoming coupled to our code. That brings down the speed of refactoring or new development because every time we change code, we need to change the tests to match the implementation. That brings down our overall productivity. And finally blaming it on tests, we would stop writing them altogether. Back to square one! Mocking tools have a purpose, but if we mock everything, we get our tests tightly coupled to the implementation, adding to the problem. Mocking simple data-structures and VOs is not meaningful, we never test their methods separately, they are not supposed to be tested. (And yes, VOs are data structures, let us not get into that here.) Mocking external libraries is risky, because we then verify their actual behaviour only at runtime, which is exactly what we are trying to avoid by writing tests.

JMockit is a powerful tool, a little too powerful, and harmful if we are not careful. Despite the misuse that we have done, it could do all those things is itself marvelous. I am not convinced to blame it on JMockit, it is as Uncle Ben said to Peter Parker: ‘With great power comes great responsibility’. What we did, is our fault, we should have been more responsible with it. I wish I could go back and change the way we used it, or overused it, but our life is not a Git repository.

Luckily though, we have identified these issues and their severity before they start heavily weighing us down. What we need to do first is avoid more such tightly coupled tests from getting in. The course of action now seems like along with training the team on how to be more responsible with tests (which by the way needs to be a continuous process), we need to identify reviewers and train them on spotting such instances. Revising the review process to have reviews through identified reviewers and not just peer reviews.

Opinionless Comparison of Spring And Guice as DI frameworks

Opinionless Comparison of Spring And Guice as DI frameworks

Recently I had to delve into the play framework for a particular microservice at work. Now it is not exactly new, nor is Guice, nor DI, but coming from Spring world it was still a big shift in approach. There is a lot of documentation comparing Spring with Guice, stating which is better, why and how. In general these articles discuss specific points where these two frameworks differ in their approaches and which approach seems better to the author. I am not sure these articles really help someone trying to take a dip in the other framework. We know the differing opinions, as they are stated by the authors of the respective frameworks in their own documentation as well, another person (article’s author) reiterating it with an incomplete comparison of these frameworks does not sound helpful. What would work much better is a direct mapping of features, without author’s opinion (Didn’t this sound like an opinion). That should help someone getting into Spring from Guice world or vice a versa.

Now let me warn you, since these are different frameworks for the same purpose, DI (Dependency Injection), they exist for their differences. Hence, there cannot be one-to-one mapping of features/differences in these frameworks. What we can get instead is mapping of similar features and that is what we will have. If nothing else, the comparison below should help someone find the right documentation for what they are trying to do, instead of wondering what to look for.

Another point, we are here discussing Spring and Guice only on their dependency injection approaches and not as web frameworks, AOP, JPA abilities, their ecosystem or any other features they provide. That is for another time maybe, but not today.

Application level @Configuration
Extend AbstractModule, comes closest to that. It defines a part of your application; multiple modules can depend on each other in an application. (Unless your service is too small)
There is no classpath scanning in Guice. (keep reading…)
@Singleton with “bind() with/without .to()” in Module
@Scope(“”); singleton (DEFAULT), prototype, request, session, global-session
Default is unscoped, similar to prototype in Spring, @Singleton, @SessionScoped, @RequestScoped, custom.
eager/lazy differ for production and development.
@Autowired, @Inject
@Inject (from javax or from guice package)
@Qualifier / @Named, Names.named,

annotatedWith and @BindingAnnotation
@Provides or implement Provider<T>
@Bean with @Autowired field in it
Explicit constructor binding: .toConstructor(A.class.getConstructor())
@Named with Names.bindProperties() in your module
Injecting static fields can be achieved with @Autowired on non-static setter method.
For static fields, use .requestStaticInjection() in your Module
ApplicationContext (BeanFactory to be precise)
@Autowired with context.getBean(Clazz, Object…)
@AssistedInject. Allows for using params, with injected beans to instantiate objects.
Provider<T> with FactoryProvider; FactoryModuleBuilder
@PostConstruct, @PreDestroy
No Support for lifecycle events. (extensions)

Let’s also see a few more points which would not fit well in a tabular form:
  • One can add more capabilities to Guice with plugins and there are a few actively maintained like Governator from Netflix. Spring can be extended using BeanPostProcessor or BeanFactoryPostProcessor in your application, but I was unable to find a plugin for extending Spring’s core DI abilities.
  • Unlike Spring, wiring in Guice (called binding) is plain Java, and so Guice has compile time verification of any wiring we do. Spring depends on metadata through annotations, which are not checked during compilation, does not have this feature and exceptions are at runtime.
  • Classpath scanning can be achieved in Guice by extending it. (Some plugins provide this, but governator for one has deprecated it.)
  • Lack of classpath scanning in Guice, most likely, considerably reduces the application startup time in comparison to Spring.
  • In Guice an Interface can declare the default implementation class (is it odd, Spring people?), @ImplementedBy annotation, which can be overridden by .bind() if found in a module. Similarly the interface can declare the configuration class which generates the instance: @ProvidedBy
  • I know I said we are not going to discuss any other abilities, but this one is a little interesting; Guice has built-in support for AOP, in Spring we need an additional dependency.
  • Not a difference, but a point to note: both frameworks have similar injection types, Constructor, method and field.

I have tried to be as opinionless as possible when writing the above piece; although there are a few things that I find important to note.
  • Guice is very much a non-magical (in the words of Guice authors) dependency injection framework, you can literally see DI happen, with the code that you write and can read.
  • Thankfully, Guice has no beans.. NO BEANS! How many beans do we have to remember and disambiguate before it is too much? Javabeans, Enterprise Javabeans, Spring Beans, Coffee Beans, Mr. Bean and I might still have missed a few others!
  • Guice still feels like java, you see, it does believe in extending classes, Spring nowadays seems to believe only in annotations, so much so that a few folks I asked around can’t even remember what ‘extends’ keyword stands for! 😉

So which one is better? Now, that was not the question we were hoping to answer!