0

I'm building a Spring Application using a Neo4j database. I have some services, that implement basic database-functions like persisting a user or finding a user by his username. Since I implemented some restraints, for example that it's not possible to delete a not existing user, i want to test my service. My wish would be having a test that builds a temporary Neo4j graphdb like described in http://neo4j.com/docs/stable/tutorials-java-unit-testing.html. But additionally I want to autowire my UserService into the test, do some operations on the temporary database and destroy the temporary database in the end again. I'm expecting that I can solve this with TestConfigurations, but since I'm not really experienced with Spring or Neo4j, it's not that simple.

I have the following configuration

@Configuration
@EnableNeo4jRepositories(basePackages = "de.myapp")
@EnableTransactionManagement
public class UserTestConfiguration extends Neo4jConfiguration{

  @Bean
  public UserService userService() {
    return new UserBean();
  }

  @Bean
  public Neo4jServer neo4jServer() {
    //This is probably wrong since i really want to connect to the impermanent db
    return new RemoteServer("http://localhost:7474");
  }

  @Bean
  public SessionFactory getSessionFactory() {
    return new SessionFactory("de.myapp");
  }
}

And the following test-class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TSUserTestConfiguration.class)
public class TSUserBeanTest {

  private GraphDatabaseService graphDb;

  @Autowired
  private TSUserService userService;

  @Before
  public void prepareTestDatabase() {
    graphDb = new TestGraphDatabaseFactory().newImpermanentDatabase();
  }

  @After
  public void destroyTestDatabase() {
    graphDb.shutdown();
  }

  @Test
  public void createUserTest() {
    TSUser user = new TSUser("TestUser", "TestEmail");
    //This should create the user in the impermanent db
    userService.persistUser(user);
    //assert stuff here
  }
}

However, I get a NullPointer Exception for the graphDB in the destroy and I'm not even sure if I'm on the right way. Does someone have an example for this scenario maybe? Even a better way to integration-test my service on a temporary db is welcome.

Thanks and regards Urr4

Luanne
  • 19,145
  • 1
  • 39
  • 51
Urr4
  • 611
  • 9
  • 26

2 Answers2

3

Looks like you're using SDN 4.x. - which version?

SDN 4.0 RELEASE

Instead of a RemoteServer, you will use an InProcessServer which internally starts a new instance of CommunityNeoServer on an available local port. It will manage shut down as well, so it's ideal and recommended for tests. In your configuration, use this instead of the RemoteServer-

@Bean public Neo4jServer neo4jServer() { return new InProcessServer(); }

The dependencies required are documented in the reference guide. Further reading, the test section in this blog post.

SDN 4.1 M1

The InProcessServer is no longer available, and instead you'll want to use the Embedded Driver which will set up for you the Impermanent graph database. ogm.properties for the impermanent embedded store should contain-

driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver

Dependencies required are documented in the reference guide. An example of upgrading your tests to use SDN 4.1 can be found here.

Luanne
  • 19,145
  • 1
  • 39
  • 51
  • I'm going to try this later on, but on the first glance it looks really good, thank you! – Urr4 Mar 15 '16 at 08:56
  • Cool, if it works, please accept the answer. If not, we'll help :-) – Luanne Mar 16 '16 at 03:23
  • I tried it and currently can't get it to work. I tried adding the dependencies as in the blog you posted, but it i build test with the PersistenceContext ContextConfguration, it always get the Failed to load ApplicationContext exception, telling me it "Failed to instantiate [javax.persistence.PersistenceContext]: Specified class is an interface". – Urr4 Mar 18 '16 at 21:06
  • Am I doing something wrong? do i need to implement the Persistence context somehow? I use SDN 4.0 btw – Urr4 Mar 18 '16 at 21:09
  • Forget it, I'm an idiot :) I thought PersistenceContext was the neo4j testing configuration, that would somehow be autowired into the test. I didn't even see, that the error says JAVAX.PERSISTENCE.PersistenceContext. I got the tests to run now, so thanks for your awesome answer :) – Urr4 Mar 18 '16 at 21:16
  • Just one tiny first-world-problem: When I use the InProcessServer, i get the warning "WARN 4j.ogm.authentication.CredentialsService: XY - No credentials supplied". Is there a way to get my code warning-free? :) – Urr4 Mar 22 '16 at 10:16
0

I used the following Configuration for testing

@Configuration
@ComponentScan("my.services")
@EnableNeo4jRepositories("my.repos")
public class MyTestingConfiguration extends Neo4jConfiguration {

  @Override
  @Bean
  public Neo4jServer neo4jServer() {
    return new InProcessServer();
  }

  @Override
  public SessionFactory getSessionFactory() {
    return new SessionFactory("de.tsbros");
  }
}

And the following class for testing

@ContextConfiguration(classes = {MyTestingConfiguration.class})
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class TSUserBeanTest {
  @Autowired
  private MyService myService;

  //testing here
}

using the following dependencies

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-neo4j</artifactId>
  <version>${sdn.version}</version>
  <type>test-jar</type>
</dependency>

<dependency>
  <groupId>org.neo4j</groupId>
  <artifactId>neo4j-kernel</artifactId>
  <version>${neo4j.version}</version>
  <type>test-jar</type>
</dependency>

<dependency>
  <groupId>org.neo4j.app</groupId>
  <artifactId>neo4j-server</artifactId>
  <version>${neo4j.version}</version>
  <type>test-jar</type>
</dependency>

<dependency>
  <groupId>org.neo4j</groupId>
  <artifactId>neo4j-ogm</artifactId>
  <version>${neo4j-ogm.version}</version>
  <type>test-jar</type>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.neo4j.test</groupId>
  <artifactId>neo4j-harness</artifactId>
  <version>${neo4j.version}</version>
  <scope>test</scope>
</dependency>

Everything like described here Works like a charm.

Urr4
  • 611
  • 9
  • 26
  • Unfortunately, this solution can't help anymore. "In SDN 4.1, the InProcessServer has been deprecated." http://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#testing – Plutoz Oct 31 '16 at 17:56
  • Thanks for the heads up. I'll keep in in mind for when i upgrade. – Urr4 Nov 02 '16 at 08:28