Thursday, 25 April 2013

Testing Spring Integration

Adding Spring Integration to our project (apart from many advantages) brings drawbacks as well. One of them is more difficult testing.

Let's try to test the flow from MessageRouter to Persister via JSONHandler (please refer to the previous post

First of all, it won't be a unit test but an integration test as we need to start-up the spring context and test the flow between components.

Let's prepare spring xml config:

We're importing the application config and overriding beans with mockito mocks.

The test would look like:

Spring injects all the required components. We're mocking the behaviour, sending message to the channel and then verifying. Mocks need to be reset as well if we want to have more test methods.

By looking at the source code we don't see which object is mocked. To solve this problem (and simplify the code as well) we can use springockito.
Then in our config file we only need to import the application config without overriding any beans.

The overriding part is done in the test by using annotations:

To use springockito we need to change the context loader to SpringockitoContextLoader. 
The @ReplaceWithMock annotation is self-descriptive.
The context is dirtied after execution of each test method which is basically equivalent to resetting the mocks.
Whole project can be found at github.

Wednesday, 20 March 2013

Spring Integration vs plain Java code

Adding frameworks to our system may solve some problems and cause too much complexity at the same time.

Let's imagine a simple flow:


We have a MessageRouter object that routes received message to either XMLHandler or JSONHandler. The processed message in both handlers are then passed to Persister that is storing the message.

Modelling it is not that difficult. Here's our MessageRouter class:

Handlers:
And finally persister: We can see it in action by running the following class:
Everything seems fine here, but we have a problem - tight coupling.
Message router knows about handlers and handlers know about persister.
We would gain loose coupling and high cohesion if they weren't aware of each other which would automatically make them concentrate on one task only.

Spring Integration can help us achieve this.
It is a separate module of Spring, enabling lightweight messaging within application and supporting Enterprise Integration Patterns.

All the arrows from the above picture will be represented as channels.

The XML Spring context configuration for the channels looks pretty straightforward:

Actually it's not even required as Spring can create them by default.

Apart from the channels, our MessageRouter only role is to return the channel name to which the message will be passed.
Also the handlers and persister need to become Service Activators (their methods will be invoked when the message will go through the channel).
The config for those:
To see it in action we can run the following class:
Notice that the code is concise and simple.
The components do not depend on each other.
What is more, if we wanted to modify the flow and move Persister component in front of the MessageRouter, we would need to change the xml config to:

Changing the flow in the first version that is using plain Java code would require much more modifications.

Nevertheless we increased the complexity of our application. Now we depend on a framework and we need to maintain additional configuration in an XML file.

Another big disadvantage is testing. We could easily unit test the previous code using mocks. Now we need to test the Java code and Spring Integration configuration as well, which is not that simple.
I'll show how to do it in the next post.

Friday, 15 February 2013

MarkLogic Java client

MarkLogic is a NoSQL document database that allows to handle XML efficiently.

Let's take a look how to setup MarkLogic database instance on a local machine and write a simple application that will perform CRUD and searching operations on XML documents.

First of all, we will need to download MarkLogic server (account is required).
Installation and starting procedures are described here - they're pretty straightforward.
When server is already started, we need to create a new database with REST API instance and a user having write access - follow this link.
REST is used by the Java client as a communication protocol but we can also use it manually in our browser.

Once database is created we can start writing the client code.

Let's start with setting up required dependencies:
To use MarkLogic Java client we need to specify MarkLogic maven repository. We'll also use xml-matchers library to compare created XML documents.

Here's an example of XML document that will be representing person:
Let's define an interface that will allow some simple CRUD and searching operations:
The sample implementation could look like:
In order to perform CRUD operations we need to have DocumentManager object (in our case XMLDocumentManager as we're handling XML). It is thread-safe object (can be shared across multiple threads) and its usage is quite intuitive. Each operation needs a specific handle object - as our interface declared String, we'll use StringHandle that is being populated with the result by manager.

To do query operations QueryManager is required. There are many types of queries, we'll use searching by element value.
It's a little bit more complicated than simple CRUD operations - SearchHandle object is initially populated by running the query on query manager.
Then we're iterating over each SearchHandle's result represented by MatchDocumentSummary object and retrieve its URI, that is given to DocumentManager that reads full document. 
Please note that the number of returned documents has been limited to 10.

The integration test (it requires running MarkLogic server):
In setUp() method DatabaseClientFactory creates DatabaseClient based on the given credentials (they need to be the same as the one used during setting up the database).
Once we have the client we can create managers needed by the implementation.

One thing to note: when manager cannot find the document it throws ResourceNotFoundException.

The whole project can be found at github.


Wednesday, 6 February 2013

Spring Data JPA sample project

In previous post I showed how to setup a sample project with JPA and Hibernate.
Even though it wasn't difficult, there was a main disadvantage - we need to do a lot of coding around our DAO objects even if we want only simple operations.
Spring Data JPA helps us reduce data access coding.

Let's start with defining dependencies:

Compared to previous project there are more dependencies because of Spring. spring-test is needed to allow our test use the spring context. And this time we're going o use HSQLDB.

pesistence.xml  is much smaller because the persistence configuration will be defined in spring context.

Please note that Hibernate is still the persistence provider. The Person class is exactly the same as before.

The context is defined as:

We need to specify dataSourceentityManagerFactory and transactionManager.
The pl.mjedynak package will be scanned by spring to do autowiring.
Spring Data JPA introduces the concept of repository which is higher level of abstraction than the DAO.
In our context we define a package with the repositories.

The only thing to do to be able to manage our Person class is to create an interface that will extend CrudRepository - it gives us basic operations like save, find, delete etc.


We can of course expand it with more sophisticated methods if we want.

The integration test is almost the same as before, except it needs to use spring context.



The whole project can be found at: https://github.com/mjedynak/spring-data-jpa-example

Friday, 25 January 2013

Hibernate JPA sample project

Here's a simple example of a project that uses JPA with Hibernate as default implementation.

Let's start with the required dependencies:

We're going to use the embedded Derby database.

We will also need the persistence.xml placed in META-INF directory on our classpath :

We're setting Hibernate as our persistence provider and Derby as JDBC driver.
Entity class Person is also specified as belonging to this persistent unit.

It's defined as:


In order to manage Person we need some kind of DAO.  Let's define an interface PersonDao:

For simplicity it has only methods for adding person and finding all persons.

The sample implementation could look like:


And the most important - integration test that checks if everything is glued together correctly:


The whole project can be found at:  https://github.com/mjedynak/hibernate-jpa-example

To sum up:
it's quite easy to create JPA with Hibernate project, however every entity class needs it's own DAO (unless we use a generic one).
In the next post I'll take a look at Spring Data Jpa project that solves that impediment.

Sunday, 18 November 2012

Mutation testing with PIT

How can we know that our unit tests are good?

Code coverage can't say that we have proper unit tests - it's just a side effect of using TDD.
It says what code has been executed in the unit test - we can write a test which just executes a method and without any assertions we'll have 100% code coverage.

Let's take a look at the following class:

It's a simple class that tells us if a given number is higher or equal to zero.

Let's take a look at the unit test:


When we execute cobertura on this test, we will see 100% coverage, both line and branch, even though it forgets about the case where the number is 0.

Mutation testing is an idea that tries to measure the quality of unit tests. They are run against modified version of the source code (by applying various mutators - hence the name). If the application code is changed, it should produce different result, therefore the unit test should fail. If it doesn't fail, it may indicate problem in the test suite.

PIT (http://pitest.org/) is a bytecode mutation testing system that automatically applies mutators to the application code.

If we run it against above mentioned class, it will produce a nice HTML report saying that 'changed conditional boundary' has survived - which means that we didn't test all boundary conditions.

We can integrate execution of PIT into our build (there are plugins for maven, ant and gradle) or we can execute it within our IDE (plugins for Eclipse and IntelliJ - that one I've created recently).

The project is actively developed, so we can expect more features to come.

Wednesday, 3 October 2012

JUnit - hamcrest incompatibility

When we're using the latest version of JUnit (4.10) and hamcrest (1.3) together we might come across an unexpected behaviour.

Let's take a look at a simple test:

We might think that this test will fail because of the assertion, but the result is:

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V

That's because the default JUnit has a dependency to hamcrest 1.1 and also the artifact org.junit:junit has some hamcrest classes inside its jar. The hasSize matcher is not present in 1.1.

To avoid this problem we need to declare following dependencies in our project:

We need to use JUnit distribution that doesn't have any hamcrest internals and we need to exclude hamcrest dependency as well. What's interesting, we will not bump into this behaviour unless our assertion throws an error.