Nuxeo Core Developer Guide

Testing a Datasource

Updated: November 7, 2024

To use a datasource from a unit test, you need to set up the datasource from the unit test itself.

The nuxeo-runtime-datasource bundle provides some framework for you to register datasource in JNDI through Nuxeo contributions instead of relying on a container like Tomcat to do it for you.

Depending on Nuxeo-Runtime-Datasource and a Few Others

In your POM, add dependencies to:

  • org.nuxeo.runtime:nuxeo-runtime-datasource
  • org.nuxeo.runtime:nuxeo-runtime-test
  • org.nuxeo.runtime:nuxeo-runtime-jtajca
  • org.nuxeo.ecm.core:nuxeo-core-storage-sql-test

Contributing a Datasource Definition

You first need to define your datasource. For instance in the file OSGI-INF/datasource-contrib.xml add:

<?xml version="1.0"?>
<component name="org.nuxeo.project.sample.datasource.test">
  <extension target="org.nuxeo.runtime.datasource" point="datasources">
    <datasource name="jdbc/foo" driverClassName="org.h2.Driver"
      maxActive="20" maxIdle="5">
      <property name="url">jdbc:h2:${ds.test.home}/db</property>
    </datasource>
  </extension>
</component>

Deploying the Datasource from the Unit Test Setup

As our example datasource contains a variable for the storage path itself, we initialize this variable from the test code before reading the contribution. Of course you could hardcode things if you prefer.

Using JUnit4 and the Nuxeo FeaturesRunner

You may want to use a Feature. See DatasourceFeature.java.

import java.io.File;
import org.apache.commons.io.FileUtils;
import org.nuxeo.ecm.core.test.CoreFeature;
import org.nuxeo.ecm.core.test.TransactionalFeature;
import org.nuxeo.runtime.test.runner.Deploy;
import org.nuxeo.runtime.test.runner.Features;
import org.nuxeo.runtime.test.runner.FeaturesRunner;
import org.nuxeo.runtime.test.runner.LocalDeploy;
import org.nuxeo.runtime.test.runner.SimpleFeature;

@Features({ TransactionalFeature.class, CoreFeature.class })
@Deploy({ "org.nuxeo.runtime.datasource", "org.nuxeo.project.sample.tests" })
@LocalDeploy("org.nuxeo.project.sample.tests:OSGI-INF/datasource-contrib.xml")
public class DatasourceFeature extends SimpleFeature {

    private static final String DIRECTORY = "target/test/h2";

    private static final String PROP_NAME = "ds.test.home";

    private File dir;

    private String oldValue;

    @Override
    public void initialize(FeaturesRunner runner) throws Exception {
        dir = new File(DIRECTORY);
        FileUtils.deleteQuietly(dir);
        dir.mkdirs();
        oldValue = System.setProperty(PROP_NAME, dir.getPath());
        super.initialize(runner);
    }

    @Override
    public void stop(FeaturesRunner runner) throws Exception {
        FileUtils.deleteQuietly(dir);
        if (oldValue != null) {
            System.setProperty(PROP_NAME, oldValue);
        }
        super.stop(runner);
    }
}

Using the Old SQLRepositoryTestCase

This is not supported anymore since Nuxeo 7.3.

import java.io.File;
import java.sql.Connection;
import javax.sql.DataSource;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.nuxeo.ecm.core.storage.sql.SQLRepositoryTestCase;
import org.nuxeo.runtime.api.DataSourceHelper;
import org.nuxeo.runtime.api.Framework;
import org.nuxeo.runtime.jtajca.NuxeoContainer;

public class TestDatasourceJUnit3 extends SQLRepositoryTestCase {
    private static final String DIRECTORY = "target/test/h2";

    private static final String PROP_NAME = "ds.test.home";

    @Override
    public void setUp() throws Exception {
        super.setUp();
        // Required since 5.6
        NuxeoContainer.installNaming();
        File dir = new File(DIRECTORY);
        FileUtils.deleteQuietly(dir);
        dir.mkdirs();
        Framework.getProperties().put(PROP_NAME, dir.getPath());
        deployBundle("org.nuxeo.runtime.datasource");
        deployContrib("org.nuxeo.project.sample.tests",
                "OSGI-INF/datasource-contrib.xml");
        // Required since 5.7
        fireFrameworkStarted();
    }

    @Override
    public void tearDown() throws Exception {
        // Required since 5.6
        if (NuxeoContainer.isInstalled()) {
            NuxeoContainer.uninstallNaming();
        }
        super.tearDown();
    }
}

Using the Datasource in the Test

See TestDatasource.java.

@Test
public void test() throws Exception {
    DataSource ds = DataSourceHelper.getDataSource("foo");
    Connection conn = ds.getConnection();
    try {
        // ... use the connection ...
    } finally {
        conn.close();
    }
}