Mike
Mike

Reputation: 150

Why instantiate new DbContext for each step of test

In the Entity Framework Core documentation on Testing with SQLite, the sample code instantiates a new DbContext for each step of a test. Is there a reason for doing this?

    // Copied from the docs:
    [Fact]
    public void Add_writes_to_database()
    {
        // In-memory database only exists while the connection is open
        var connection = new SqliteConnection("DataSource=:memory:");
        connection.Open();

        try
        {
            var options = new DbContextOptionsBuilder<BloggingContext>()
                .UseSqlite(connection)
                .Options;

            // Create the schema in the database
            using (var context = new BloggingContext(options))
            {
                context.Database.EnsureCreated();
            }

            // Run the test against one instance of the context
            using (var context = new BloggingContext(options))
            {
                var service = new BlogService(context);
                service.Add("http://sample.com");
                context.SaveChanges();
            }

            // Use a separate instance of the context to verify correct data was saved to database
            using (var context = new BloggingContext(options))
            {
                Assert.Equal(1, context.Blogs.Count());
                Assert.Equal("http://sample.com", context.Blogs.Single().Url);
            }
        }
        finally
        {
            connection.Close();
        }
    }

    // Why not do this instead:
    [Fact]
    public void Add_writes_to_database()
    {
        // In-memory database only exists while the connection is open
        var connection = new SqliteConnection("DataSource=:memory:");
        connection.Open();

        try
        {
            var options = new DbContextOptionsBuilder<BloggingContext>()
                .UseSqlite(connection)
                .Options;

            // Create the schema in the database
            using (var context = new BloggingContext(options))
            {
                context.Database.EnsureCreated();

                var service = new BlogService(context);
                service.Add("http://sample.com");
                context.SaveChanges();

                Assert.Equal(1, context.Blogs.Count());
                Assert.Equal("http://sample.com", context.Blogs.Single().Url);
            }
        }
        finally
        {
            connection.Close();
        }
    }

Why not instantiate the context once, and use that instance throughout the entire test method, as shown in the second code sample?

Upvotes: 1

Views: 1175

Answers (1)

D Stanley
D Stanley

Reputation: 152501

Because that's how contexts should be used. They should be created per request and disposed of.

One practical reason is to ensure that you're going back to the data source each time instead of just looking at state within the context.

Upvotes: 2

Related Questions