Neo4j Unit Testing with GraphUnit

Luanne Misquitta

by Luanne Misquitta

Testing the state of an Embedded Neo4j database is now much easier if you use GraphUnit, a component of the GraphAware Neo4j Framework.

I tried replacing an existing Flavorwocky unit test with GraphUnit to check out the benefits. Let’s walk through a before-after case study.

The test

The unit test in question is the one to test that a Pairing is saved correctly. A pairing must have exactly two ingredients. Each Ingredient node has a name; a Pairing has an affinity and an array of allAffinities (all affinities ever assigned to the pairing).

Pairing Model


Pseudocode to test that my code saved a pairing correctly in Neo4j:

    1. Execute Cypher statement to find the first Ingredient by name (Chicken)
  • a. Fail if no results returned
    1. Use the core Java API to check that a pairsWith relation exists to another node with label Ingredient and name Garlic
  • a. Fail if no relation exists
  • b. Fail if the other Ingredient node has the wrong/missing name
    1. Use the core Java API to find the Pairing node from the two ingredient nodes and check that the properties on Pairing are set correctly
  • a. Fail if the Pairing node was missing or the properties were incorrect
    1. Make sure that the graph contains ONLY these nodes and relations and no incorrectly created nodes floating around

That’s quite a bit of code to write just to test a simple structure. And it’s difficult to remember what it does and modify it when you come back to it after a considerably long period of time.

GraphUnit allows you to compare the entire state of your graph to a subgraph represented in the form of a data-creating Cypher statement.


Writing a Cypher statement to represent a subgraph with two ingredients and a pairing is very easy, and my test code reduces to

 String ingredientSubgraph =  
         "create (i1:Ingredient {name: 'Chicken'}), " +
         "(i2:Ingredient {name: 'Garlic'}), " +  
         "(i1)<-[:hasIngredient]-(p:Pairing {affinity: 0.45, allAffinities: [0.45]}), " +  
         "(p)-[:hasIngredient]->(i2) merge (i1)-[:pairsWith]-(i2)";  
 GraphUnit.assertSameGraph(getGraphDb(), ingredientSubgraph);  

This will make sure that my graph contains nothing but the nodes and relations created by the Cypher statement, and that every property matches exactly. Pretty cool.

GraphUnit exposes another method to match the existence of a subgraph in the entire graph. This will verify only the subgraph specified and ignore other nodes and relations.

GraphUnit.assertSubgraph(getGraphDb(), ingredientSubgraph); 

Check out the entire test in a simplified version of the flavorwocky project.

Note at this point in time, GraphUnit requires a handle to org.neo4j.graphdb.GraphDatabaseService hence it currently supports testing against an Embedded or Impermanent graph database.

An ImpermanentGraphDatabase is great to unit test against. Depending on your testing preferences, you can decide to create a new empty graph for every test or build up on the same one for a series of tests. BaseTest uses standard jUnit fixtures to do this. I inject the desired flavour of the GraphDatabaseService into a factory class that produces the right database to be used either in production mode or testing, and that’s all there is to it.

Don’t just use it to test code

Apart from testing code, I found another use for GraphUnit this weekend- verifying that data imported into a graph is correct. I’m creating a 2014 World Cup graph using LOAD CSV to import a variety of data from scattered csv files. Visually inspecting the graph or querying it after an import run isn’t quite a productive activity, so now I’ve got a single unit test that uses GraphUnit to verify subgraphs in my world cup database.

public class ImportTest extends BaseTest {  

   public void testGoal() {  
     String goalSubgraph = "Match (country:Country {name: 'Australia'})<-[:HomeCountry]-(player {name: 'Tim CAHILL'})," + 
      " (m:Match {id: 4}), (min:Minute {id: 35}) " + 
      " create (player)-[:Scored]->(goal:Goal{type: 'regular'})-[:In]->(m)" + 
      " create (goal)-[:AtMinute]->(min)";  
     GraphUnit.assertSubgraph(getGraphDb(), goalSubgraph);  
   public void testReferee() {  
     String refSubgraph = "match (m:Match {id:4}) match (c:Country {name:'Ivory Coast'})" + 
      " create (m)-[:Referee]->(r:Referee {name:'Noumandiez DOUE'})-[:HomeCountry]->(c)";  
     GraphUnit.assertSubgraph(getGraphDb(), refSubgraph);  

It’s simple to get started

  • include the maven dependency and you’re away!

Share this blog post:

comments powered by Disqus