Fast empty Raven DB sandbox databases for unit tests

Say you you have some NUnit/xUnit/Mspec tests that require a live Raven DB instance. Specifically:

  • You do not want your test to be affected by any existing documents, so ideally the Raven DB database would be completely empty.
  • Your test may span multiple document sessions, so doing it all within a single transaction and rolling it back is not an option.
  • You want your tests to run fast.

What are your options?

Raven DB currently has no DROP DATABASE or equivalent command. The recommended method is simply to delete Raven DB’s Server\Data or Server\Tenants directories, but this requires restarting the Raven DB service (expensive). Also any live document stores may throw an exception at this point.

Multi-tenanting

One option that Raven DB makes very cheap, however, is spinning up new database instances (aka tenants). In fact all you need to do is specify a new DefaultDatabase and the document store will spin a new database up for you. For example:

var store = new DocumentStore
    {
        Url = "http://localhost:8080",
        DefaultDatabase = "MyAppTests-" + DateTime.Now.Ticks
    };
store.Initialize();

// now you have an empty database!

Pretty easy huh? Here’s a little test helper I wrote to help manage these sandbox databases, stores and sessions. Here’s how you would use it in a tenant-per-fixture test:

[TestFixture]
public class When_doing_something
{
    [TestFixtureSetUp]
    public void SetUp()
    {
        RavenDB.SpinUpNewDatabase();

        using (var session = RavenDB.OpenSession())
        {
            // insert test data
        }
    }

    [Test]
    public void It_should_foo()
    {
        using (var session = RavenDB.OpenSession())
        {
            // run tests
        }
    }
}

You can grab it here as a gist on Github: https://gist.github.com/1940759.

Note that if you use this method, a number of sandbox databases will (of course) build up over time. You can clean these up you by simply deleting the Raven DB data directories. (See gist for an example batch file you can throw in your source control to do this.)

9 thoughts on “Fast empty Raven DB sandbox databases for unit tests

  1. Richard,

    Why do you do it like this?
    RavenDB contains explicit support for testing.

    new EmbeddableDocuemntStore { RunInMemory = true}

    This will give you RavenDB running in memory, no need to setup a new database.

  2. Hi Richard,

    Most debugging situations shouldn’t require use of RavenDB studio, but for those that do you can expose the embedded database via HTTP:


    var documentStore = new EmbeddableDocumentStore
    {
    DataDirectory = "Data",
    RunInMemory = true,
    UseEmbeddedHttpServer = true
    };

    That way you get both the ability to browse and the performance benefits of using an embedded document store. Also, your tests would no longer have a dependency on an external service.

  3. So what do I point the Studio at if I’m running embedded in memory? The url, “localhost:8080” doesn’t seem to work…

    My browser keeps showing “connecting….”

  4. Nice solution, normally id use an EmbeddableDocumentStore but currently no async sessions are allowed on EmbeddableDocumentStore , which means to test anything that makes use of an async session i need to use this.

    I also found i needed to force RavenDB to create the new database, maybe it was a difference in version?

    using Raven.Client.Extensions;

    store.Initialize();
    store.DatabaseCommands.EnsureDatabaseExists(Store.DefaultDatabase);

  5. HI-

    I am using ravendb in my mvc application.

    i want to write test cased for my controllers and relevant logic code classes.

    i want to use code classes but testing cholud be done locally i mean to say for insertion/updation/deletion etc any CRUD operation should perform locally.

    how should i do, please help me out (send me any app helps me ton)…….

    Thanks In Advance,
    Hari

Comments are closed.