Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration tests of a polyglot stack (Java/MongoDB/RabbitMQ...)

I am aware RabbitMQ is written in Erlang and thus can't be embedded in a JVM like we would do with the ActiveMQ JMS broker for exemple.

But actually there are some projects that are done in another language and that can easily be embedded for integration tests.

For exemple, MongoDB, written in C++, can be easily started/stopped in the context of a JVM integration test with: https://github.com/flapdoodle-oss/embedmongo.flapdoodle.de

There is also someone porting it to Java: https://github.com/thiloplanz/jmockmongo/


So I just wonder how can we do integration tests when my application is written in Java, and the other technology is in another langage (like Erlang for RabbitMQ)?

In general what are the good practices?

I see 3 main solutions:

  • Starting a real RabbitMQ
  • Embedding a JVM port of the technology in the currently used Langage
  • Use standard technologies so that a technology in Erlang may have the same behavior and communication layer that another one in Java (RabbitMQ / Qpid / StormMQ implementing AMQP)

Is there a Maven/Sbt/Ant plugin to startup a temporary RabbitMQ broker? Any project to support Junit/TestNG RabbitMQ before a test class?

I have seen that there is an opensource implementation of AMQP in Java: Apache Qpid Has someone any experience using this implementation for integration testing while in production there is RabbitMQ? Is it even possible? I am using Spring Integration.


By the way, I just noticed that the Spring-AMQP project mention on its github readme:

Many of the "integration" tests here require a running RabbitMQ server - they will be skipped if the broker is not detected.

like image 615
Sebastien Lorber Avatar asked Mar 04 '13 14:03

Sebastien Lorber


4 Answers

If it were me, I would look at mocking the stack component in question. What's the best mock framework for Java? (although not a great Stack Overflow question) and Mock Object might help get you going.

Mocking the components makes testing much easier (IMHO) than trying to "live test" everything.

like image 102
Mark Leighton Fisher Avatar answered Nov 03 '22 18:11

Mark Leighton Fisher


In the past I have used a virtual machine that had a fresh install of RabbitMQ running. Developers would run it constantly and our CI server would start a new VM for each revision of the code. Our tests would fail if they could not connect to the server instead of skipping the tests as a lack of integration tests is a serious problem.

This tends to work reasonably well and prevents needing to start and stop RabbitMQ for the tests. Our tests were split up to use vhosts for isolation and a few calls to create vhosts on demand so we could parallelize tests is we needed to.

like image 43
Philip Cristiano Avatar answered Nov 03 '22 20:11

Philip Cristiano


I will tell you my opinion on the Apache QPid vs Rabbit MQ as I worked with both. My opinion is that they do 'extend' AMQP, but are very different. If in production you will have Rabbit MQ, then use the same one in tests - also the same version, patches, fixes, etc. There are things that Apache Qpid can do and Rabbit MQ can not and vice-versa.

Stating the obvious integration tests are done so that you could test the integration of the application. I would start an instance of Rabbit MQ.

like image 2
Eugene Avatar answered Nov 03 '22 18:11

Eugene


Based on Philip Christiano's answer that says to use VM's, now we have Docker and I think it is the way to go to embed different technologies in docker containers.

One can start a docker container containing a RabbitMQ server, and it will be faster than using VM's because docker containers are lightweight and startup time is a lot better.

There are some maven plugins that permit to start docker containers, for exemple: http://www.alexecollins.com/content/docker-maven-plugin/

like image 2
Sebastien Lorber Avatar answered Nov 03 '22 18:11

Sebastien Lorber