了解内存数据库的Dispose方法

问题描述

我的所有单元测试都有这个基类,它可以旋转内存数据库

public abstract class TestWithsqlite : Idisposable
{
    private const string InMemoryConnectionString = "DataSource=:memory:";
    private readonly sqliteConnection _connection;

    protected readonly TodoDbContext DbContext;

    protected TestWithsqlite()
    {
        _connection = new sqliteConnection(InMemoryConnectionString);
        _connection.open();
        var options = new DbContextOptionsBuilder<TodoDbContext>()
                .Usesqlite(_connection)
                .Options;
        DbContext = new TodoDbContext(options);
        DbContext.Database.EnsureCreated();
    }

    public void dispose()
    {
        _connection.Close();
    }
}

我的问题是:如果我在一个测试中调用DbContext.something,是否是dispose方法确保在测试结束时关闭数据库实例?这样,对于下一次测试,当我再次调用DbContext时,它是一个新实例吗?

解决方法

由于您的测试类用于多个测试,所以对于一个测试应该具有唯一性的东西使用基类是一个坏主意。

您想精确地控制 何时以及如何打开数据库以及何时以及如何将其从内存中删除。

这意味着您的类不应被继承,而应由每个测试使用。

使您的类成为可以实例化的普通类,并将通过方法或属性提供DBContext。在构造器中打开并创建数据库,然后像以前一样在dispose方法中关闭并删除数据库。

您的测试应从实例化此类的using块开始。

在using块中,您的测试可以使用该类及其提供的DBContext。无论您如何离开测试,using块都将负责处理(代码可能最终会引发异常)。

我不记得它是如何工作的,但是我认为您可以为内存数据库命名。这样做可能是个好主意,否则您将必须确保测试永远不会并行运行。

,

xUnit documentation对此进行了描述。因此包含测试的类可以实现IDisposable。默认情况下,xUnit将隔离运行测试类中的每个方法,并将调用Dispose,因此每个测试中的任何对象实例都是唯一的。

如果您要共享对象实例,则可以使用固定装置,但这听起来像您希望在测试之间进行隔离,默认情况下是存在的。

因此,如果您现在直接将测试方法添加到问题中的类,则每个测试的上下文应该是唯一的。您应该能够通过在测试方法(或Dispose)中放置断点,然后调试测试以查看会发生什么来进行测试。

,

每个单元测试都应有一个新的DbContext。您不希望测试之间有任何依赖关系。因此,在测试结束时调用dispose是正确的。

,

当我查看“ SQLite.Net帮助”时,文档指出: 处置-处置并最终确定连接。

换句话说,所有SQLiteConnection成员都变得无效,所有资源都被释放。 问候 马丁

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...