Last Updated: February 25, 2016
·
1.396K
· sslotsky

Database cleaning in Entity Framework

Why do we need it?

Ideally, unit tests don't require data persistence, but this is the real world and some tests will need to run code that reads from the database. If your software is designed well, mocking your database context might be an option for you.

However, if you opt to persist data for integration tests, or for whatever other reason, it is quite handy to have some means of cleaning up your test data before or after they run. Manually deleting the records you create for testing is very cumbersome, and foreign key constraints make it much more difficult to simply empty all your database tables. In this situation, we desperately want something automatic to do this for us.

How do we achieve it?

Luckily, with a bit of SQL, for any given table X, we can find all tables that have foreign key constraints pointing to X, and with a little programming, we can resolve these tables recursively and delete from the bottom of the tree on upward.

For this purpose, I've created a package called DatabaseCleaner. The source code is available on GitHub.

How can I use it?

Using it could not be simpler. After installing the package from NuGet, you can clean a tree of tables with two lines of code. All you need to specify is a table to start with and a Func that will return a new instance of a DbContext derivative. Like so:

public class FooTest
{
    [TestInitialize]
    public virtual void Before()
    {
        var scheduler = new Scheduler(() => new MyDbContext("name=MyConnectionString"), "Client");
        scheduler.Schedule();
    }
}

How mature is it?

As of this writing, the package is brand new and very basic. There are no doubt some features that would be convenient to have, such as:

  1. Provide an entity class name that DatabaseCleaner will resolve to a table name.
  2. The ability to automatically clean all tables without specifying a starting point.

Fortunately, the package is open source. Feel free to fork and submit a pull request for anything you deem to be useful!