DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Test Driven Development and Neo4J: Using @Rule and Avoiding Containers

Test Driven Development and Neo4J: Using @Rule and Avoiding Containers

Rob Williams user avatar by
Rob Williams
·
Feb. 20, 12 · Interview
Like (0)
Save
Tweet
Share
6.52K Views

Join the DZone community and get the full member experience.

Join For Free

Been doing some coding with Neo4J. Pretty interesting experience so far, but one thing is for sure: being able to write seriously sophisticated code that has a large, complex model underneath it, from inside unit tests that run in a few milliseconds is, as the bloodsucking credit card commercial says, priceless. There are still a couple of challenges to consider, but the reality is with a simple custom rule (using JUnit 4), you can have an embedded database that will be ready for each test, and cleaned up after each one.

Here is the code. Because of the inability to put a @Rule inside a rule implementation, the folder is passed in. Notice the shutdown is commented out. Per my prior post, that is because the folder is already gone by the time this gets called. Turns out it‘s not really needed. If you manage the resource yourself, however, you have to call shutdown or your deletes will not wipe the dir completely.

package com.ontometrics.testing;

import org.junit.rules.ExternalResource;
import org.junit.rules.TemporaryFolder;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Custom @Rule implementation for making an embeddable graph database for use
* in tests.
* <p>
* Does the setup and teardown of the database, creates a transaction.
*
* see EmbeddedGraphDatabase, {</code>link ExternalResource}
*/
public class TestGraphDatabase extends ExternalResource {

private static final Logger log = LoggerFactory.getLogger(TestGraphDatabase.class);

public TemporaryFolder tempFolder;

private EmbeddedGraphDatabase database;
private Transaction transaction;

public TestGraphDatabase(TemporaryFolder tempFolder) {
this.tempFolder = tempFolder;
}

@Override
protected void before() throws Throwable {
super.before();
}

@Override
protected void after() {
super.after();
transaction.finish();
// database.shutdown();
}

public EmbeddedGraphDatabase getDatabase() {
if (database == null) {
log.debug("created database in: {}", tempFolder.getRoot().getAbsolutePath());
database = new EmbeddedGraphDatabase(tempFolder.getRoot().getAbsolutePath());
transaction = database.beginTx();
}
return database;
}

public Transaction getTransaction() {
return transaction;
}

}

Yeah, the formatting of code on here is abysmally bad.

Also, I wait until the database is asked for because getting the temp folder in Before was not working. You could do it there instead since we are passing the folder in.

I am burnt to a crisp on container-based testing in Java. My new meanderings are that if there is a need for a container, it‘s probably not until long into the development cycle. Which brought up a bunch of interesting questions:

  1. Doesn‘t the Rule in JUnit attempt to solve the same problem that the container does? When we write our own classes for things like EntityManagers, we quickly get dispirited about the question of how we are going to make these things magically materialize in all the places that we need them. But is that really such a big problem?? For instance, I wrote a few tests that used this rule and put objects in the db, created relations, retrieved them, etc. Then I wanted to make a repository for my entity. So I did a generic repository that uses Reflection (did this in Spring, something like it in Seam). Only, this time, I didn‘t jump right away into the Container Fry Pan. So the Repository needs an EM, big deal. Let‘s start by making one and setting it. Then I got to thinking, ‘why not make a test class (not in compile scope) that just makes your repositories for you, sticks the EM inside, then returns it? Or, why not embed a Rule for each major repository in that package‘s test equivalent? So PersonRepository extends ExternalResource.. ? Actually, PersonRepository extends TestRepository and that class could get the EMF wiring?
  2. Is there really a requirement to start calling the container into service from the very beginning? Frankly, what if we went totally naked on the domain side then had a controller layer that had some generic injection protocol (our own annotations) so we could develop all the way up through that layer with no container and then could turn on CDI or its ilk once we were up on that floor?
  3. Isn‘t there a container equivalent of the very anemia Spring was supposedly made to cure?? Yes there is friends. We‘ve all seen the DI projects where the same simplistic patterns of DAOs are repeated robotically to an inane degree.
  4. If we move away from a per-domain object/single persistence entry point, doesn‘t the container become less important? The Weld maven archetype had this idea and some of their docs too. So, instead of making a PersonRepository that ends up with 80 methods in it, you have controllers injected with the EM and then different functional requirements of the Person are associated with their context more directly. So, for instance, if we have a social bent to our app, we might have a FriendsController that manages invites and the like, and if we have security another called PersonalSecurityController that has those interactions. To me, this is less anemic, less prone to bloat, and less monocultural. It‘s also plenty easy to do without seeing the container as the master puppeteer who has to bring all the forces together.

This was what I was getting at in my post about Play. The container guys have both over played their hand and lost site of the real costs of their approach, and by staying reactionary, have failed to redirect their attention forward, and half their audience is too young to even remember the supposed glory of their birth. Furthermore, as Agile continues to turn more and more into Lean, we will see that the decade of the DI container has been anything but.

From http://www.jroller.com/robwilliams/entry/tdd_and_neo4j_rule_no

Container unit test Test-driven development Neo4j

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • NoSQL vs SQL: What, Where, and How
  • Java REST API Frameworks
  • 5 Software Developer Competencies: How To Recognize a Good Programmer
  • Use AWS Controllers for Kubernetes To Deploy a Serverless Data Processing Solution With SQS, Lambda, and DynamoDB

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: