Fast empty Raven DB sandbox databases for unit tests

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 ServerData or ServerTenants 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.)