MENU +44 (0) 333 44 GRAPH

GraphAware Blog

Neo4j Unit Testing with GraphUnit

16 Jun 2014 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

Before

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

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.

After

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 {  

   @Test  
   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);  
   }  
   
   @Test  
   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:

+1 LinkedIn
comments powered by Disqus

Popular

Recent

Posts by tag

Neo4j Conference NoSQL Czech Beginner Analytics Advanced Modelling Meetup GraphAware Intermediate GraphUnit Testing Transactions Cypher Events Spring SDN OGM Recommendations Search Elasticsearch Security Enterprise NLP HCM PeopleAnalytics HR HRTech Framework Internationalization Localization

Search this blog