Showing posts with label DBUnit. Show all posts
Showing posts with label DBUnit. Show all posts

Sunday, August 23, 2009

Bookmark and Share

Finally I found some time to continue working on a little project of mine, scriptable dataset, which makes it possible to use script snippets (in languages such as JRuby, Groovy etc.) in your DBUnit dataset files. Imagine for instance, you were building a web shop application and wanted to insert an order issued 14 days ago into your order table. Using the scriptable dataset, you can do exactly that:

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <order product="CD player" orderdate="jruby:DateTime::now() - 14"/>
</dataset>

In comparison to the original release the 1.0 version contains basically some refactorings: ScriptableDataSetConfig got a new constructor, the Java 6 ServiceLoader mechanism is used to detect standard script invocation handlers, all dependencies were updated to the current versions and the entire code base was cleaned up a little bit.

Many thanks to Kevin Hutson, who contributed a test case for using Groovy as scripting language in a dataset file. It's really great to see, how GitHub is encouraging people to contribute to open source projects by making forking and merging that easy.

To allow for using the scriptable dataset in Maven based applications, I set up a Maven repository at Google code, which hosts the project's artifacts. Just add this repo to your pom.xml or settings.xml as shown below:

1
2
3
4
5
6
7
8
...
<repositories>
    <repository>
        <id>http://gunnarmorling-maven-repo.googlecode.com/svn/repo/</id>
        <url>http://gunnarmorling-maven-repo.googlecode.com/svn/repo/</url>
    </repository>
</repositories>
...

Then add scriptable dataset as dependency as well as a binding for sl4j, which is used for logging purposes:

1
2
3
4
5
6
7
8
9
10
11
12
...
<dependency>
    <groupId>de.gmorling</groupId>
    <artifactId>scriptable-dataset</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-jdk14</artifactId>
    <version>1.5.8</version>
</dependency>
...

An example for using the scriptable dataset is shown in the project's unit test ScriptableDataSetTest.

So feel free to give it a try. I'd be glad on any comments: do you like the idea of scripting in dataset files in general, what use cases could you think of, what place for improvement do you see?

Monday, February 16, 2009

Bookmark and Share

DBUnit is a great tool when it comes to the management of test data. When doing data driven unit tests, database tables have to be populated with predefined records, that can be accessed by the code under test. DBUnit allows the specification of such test records by the means of data set files as in the following example:

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <location num="6" addr="Webster Street" date="2009-02-16"/>
</dataset>

The data that can be inserted with such data set files is pretty static by nature. DBUnit offers a bit of dynamic with its ReplacementDataSet, which allows to replace custom-defined placeholders (e.g. [SYSDATE]) with other values (e.g. new Date()). But I am aware of no possibility to use more flexible expressions to insert things like "now - 14 days" into a date field for instance.

So I set out to create a data set implementation, that allows to use scripting language expressions in its fields. Using this ScriptableDataSet, data set files like the following can be loaded and processed:

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <location num="jruby:12/2" addr="jruby:'Webster Street'.reverse" date="jruby:DateTime::now() - 14"/>
</dataset>

Having the power of a scripting language at your hands any dynamic expressions thinkable can be used in the fields of a data set – also "now - 14 days" is no problem any more.

How does it work? The scriptable data set leverages the scripting language integration API as defined by JSR 223 ("Scripting for the Java Platform"). An implementation of that API is part of Java 6, but it generally can be used with previous Java versions as well.

To use a certain language in a data set, a JSR 223 compatible engine for that language has to be added to the class path. Loads of such engines can be found at the scripting project at java.net. Having added the engine for your preferred scripting language (or by using the Rhino engine for JavaScript, which is delivered with the Java 6 JDK), a ScriptableDataSet can be created as follows:

1
2
3
4
5
6
7
8
List<Class<? extends ScriptInvocationHandler>> handlers = 
    new ArrayList<Class<? extends ScriptInvocationHandler>>();
handlers.add(TestInvocationHandler.class);

IDataSet dataSet = 
    new ScriptableDataSet(
        new FlatXmlDataSet(new File("dataset.xml")),
        new ScriptableDataSetConfig("jruby", "jruby:", handlers));

Sporting DBUnit's decorator scheme, a ScriptableDataSet is created wrapping another IDataSet. Additionally a ScriptableDataSetConfig object has to be provided, that specifies

  • the name of the scripting language to be used as understood by the JSR 223 ScriptEngineManager ("jruby")
  • a prefix that shall precede all fields containing scripts in that language ("jruby:")
  • an optional list of ScriptInvocationHandlers, that can be used to pre-process (e.g. to add common imports) and post-process scripts (e.g. to convert results into data types understood by DBUnit)

So if you like the idea of the scriptable data set, don't hesistate and get your hands on it at its git repo over at github. Do you think, it is useful at all, and if so, which scenarios for its usage could you think of?