I’ve recently posted a Tweet about my day to day life. This Tweet said “I’ve reached a point where I can test Spring code in a couple of minutes, and Java EE code in a couple of hours :o(“

I was a bit surprised to read some reactions. In fact, some people asked me to explain this Tweet a bit more… so here I am.

Who Am I? What Am I Doing?

First of all, it’s important to recap who I am and where I come from. Basically, I’ve started working for BEA Systems in 1998, that’s when I discovered J2EE 1.2. In 1999 I was working for a big BEA Systems customer (think of a famous English Airway company ;o) setting up their on-line ticketing. Yes, in 1999 I was doing micro-services (EJBs), with clusters of dozens of services talking to each other in a highly optimized binary protocol (no, not gRPC, its ancestry RMI/IIOP), aggregating logs, setting up clusters, failover, sticky sessions, scalability and so forth. All that with J2EE (and yes, it was in 1999).

When I left BEA Systems I worked on and off with Java EE and Spring. I then wrote a few Java EE books, got involved in the JCP, gave a few talks mainly on Java EE, while I kept working at my customers on Java EE and Spring.

With the entire “Java EE 8 drama” (i.e. the specification wasn’t moving anywhere), the MicroProfile, the Java EE Guardians, EE4J,…. I decided to give myself a “Java EE break”. Since last year I’ve started working with Spring Boot and Angular (thanks to JHipster). Two technologies I wasn’t very familiar with, and I have to say, I’m enjoying it !

So let me rephrase this again: I’ve mostly worked with Java EE, but I haven’t touch a Java EE project for one year, instead, I’ve been working with Spring Boot. That’s why, when I got back to Arquillian recently, it was a bit painful.

Testing

Let’s be plain here: when your code is executed in a managed environment (Java EE, Spring…) Unit Test are (mostly) useless! I have lived this for so long in my projects, that, as a joke, I launched the No Mock Movement back in 2012. Today, in the world of containers and micro services, this is even more true. What is the percentage of your unit tests compare to integration tests? And yes, by unit tests I mean “testing in isolation” with no memory database, no memory web server, no memory message broker… just pure unit tests.

Unit tests in a managed environment are useless. Integration tests are useful, therefore, they should be easy to write.

Testing with Java EE

So, what do you do when you find out that Unit Tests in a managed environment are useless? You write integration tests. And in Java EE, you can choose between Arquillian (my post from 2012), Payara APIs, TomEE APIs… only proprietary APIs actually. So when I read this Tweet I was a bit surprised:

“Proprietary specless”. Interesting. In 2013 I wrote a post on a Java EE 8 Wishlist (basically, about what I wanted to see happening in Java EE 8). Despite the fact that not much from this wishlist has happened, this is what I wrote:

Integration tests should be easier to write. Arquillian already does a fantastic job for integration testing, but we could go further. If we manage to have a single container, and therefore a single container API, then it would be easier to write tests that start a container, lookup for components, check available services, invoke code, check that interceptors have been applied, that Servlets have been constructed, that a Singleton has been initialized at startup by the container…

There is no Java EE specification for managing a container through APIs. If you want to bootstrap the container to do some integration testing, you need to go proprietary (Arquillian, TomEE APIs, Payara APIs…)… like Spring.

I wrote Arquillian tests for years (talked about it, wrote about it). For the Tweets I received, it looks like it is easier to use TomEE or Payara. I have never used those so I can’t tell. But again, this shows that testing in Java EE is not standard.

Testing with Spring

In 2002 when Rod Johnson wrote his famous Expert One–on–One J2EE Design and Development book, his chapter 3 was titled “Testing J2EE Applications“. Yes, in 2002, someone was already looking at how to test a J2EE application. And this same person created Spring, with testing in mind. If you look for the word “cluster” in the Java EE 7 specs (2013), you will only find it once. If today, in 2018, you look for the word “test” in all the Java EE 8 specs, you will not find it very often (if you take out “test” for TCK, and “test” for if statements).

I actually committed a couple of integration tests using Spring Boot recently. There is not much to say when you look at the code. I have a Spring Boot application with a main class that looks like this:

@SpringBootApplication public class BVSpringApplication { public static void main(String[] args) { SpringApplication.run(BVSpringApplication.class, args); } }

And guess what? To test this application, I just need a JUnit runner ( @RunWith(SpringRunner.class) ) and give it the name of the main class ( @SpringBootTest(classes = BVSpringApplication.class) ).

@RunWith(SpringRunner.class) @SpringBootTest(classes = BVSpringApplication.class) public class AddressEndpointTest { @Test public void blahblah() throws Exception { // blahblah } }

I won’t go into too much technical detail, but if you compare with the code I wrote for my Arquillian post in 2012, testing with Spring Boot is way simpler. With Arquillian you need to package your classes into an archive with all the dependencies (introspecting the pom.xml), and then, deploy this archive into a container. As I said to a friend back at Devoxx BE “Arquillian will be great once we get rid of Shrinkwrap“. What this means is, I don’t want to package code to test it anymore (BTW, I love Shrinkwrap ;o) With Spring, behind the scene it’s more or less the same (no packaging, but classpath scanning and bootstrapping the Spring container), but it’s way simpler.

Java EE is Dead

Of course it is! It is now called EE4J.

No, it’s not a Java EE Game Over for me (more on this blog in a few weeks ;o) but I have to say that I am enjoying my new development’s life around JHipster Microservice architecture (Spring Cloud + Angular + Netflix OSS). So I’ll stick to it for now, and I’ll keep a close look at the MicroProfile. And I really hope that EE4J / Microprofile will make sure to have a specified API to control the container (à la Wildfly Swarm), so integration testing will be easy and portable.

Conclusion

Integration tests are important in a managed environment. Even if they are difficult to maintain, they should be as easy to write as possible. Integration tests in Java EE are complex, not portable, still rely on packaging (when using Arquillian), and on a running container (even if Arquillian uses managed container). Spring was created with testing in mind, therefore, integration test were already easier to write years ago. Today, with Spring Boot, it is even easier than ever.

Coming back to the topic of this post: I’ve worked with Spring Boot for more than a year now. I can now write a Spring Boot test in a couple of minutes. Recently I had to use Arquillian. Because I hadn’t use it for a year, and due to the packaging and deployment complexity, it took me a couple of hours.

But I’m sure it will get better !

References