You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite内存数据库NUnit测试:种子数据显示异常及文件库切换咨询

问题:SQLite内存库单元测试数据查看与切换文件库的疑问

我正在使用SQLite内存数据库进行NUnit单元测试,无法像查看.db文件那样查看所有数据。本地调试器检查时仅能看到预期添加的记录,但结果视图中却显示了OnModelCreating方法中配置的测试种子数据。

ApplicationDBContext配置

public class ApplicationDBContext : IdentityDbContext<IdentityUser>
{
    public ApplicationDBContext(DbContextOptions options) : base(options)
    {
    }
    public DbSet<Ref_Category> Ref_Categorys { get; set; }
    public DbSet<Location> Locations { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Customer>().HasData(new Customer { Id = 10, Forename = "The", Surname = "Doctor", IsActive=true,IsDeleted=false});
        modelBuilder.Entity<Customer>().HasData(new Customer { Id = 11, Forename = "Martha", Surname = "Jones", IsActive = true, IsDeleted = false });         
    }
}

单元测试代码

public class BookingServicesTests : IDisposable 
{
    private bool _useSqlite;
    private SqliteConnection _connection;
    private DbContextOptions _options;
    public BookingServicesTests()
    {
        _connection = new SqliteConnection("datasource=:memory:");
        _connection.Open();
        _options = new DbContextOptionsBuilder()
            .UseSqlite(_connection)
            .Options;
        using (var context = new ApplicationDBContext(_options))
            context.Database.EnsureCreated();
    }

/// <summary>
/// Books the check out should decrease inventory of the same book.
/// </summary>
/// <param name="expectedCount">The expected count.</param>
[TestCase(9)]
public async Task Book_CheckOut_ShouldDecreaseByNumber(int expectedCount)
{
    using (var context = new ApplicationDBContext(_options))
    {
        context.BookInventories.Add(new BookInventory
        {
            BookId = 4,
            BarCode = "1111",
            InventoryCount = 10,
            IsActive = true,
            IsDeleted = false,
        });
        await context.SaveChangesAsync();

        using (var context2 = new ApplicationDBContext(_options))
        {
            var service = new BookManagerServices(context2);
            int bookId = 4;
            int customerId = 10;
            string barCode = "1111";

            // ACT
            var act = service.CheckOut(customerId, bookId, barCode, 7);

            // Assert
            Assert.AreEqual(act.Data, expectedCount);
        }
    }
}

核心疑问

  • SQLite是否应该仅显示我添加的这条BookInventory记录,而非所有种子数据?
  • 能否切换为文件型数据库用于本地测试,以便查看表中的数据?

解答

关于种子数据显示的问题

这是正常现象。你在OnModelCreating里用HasData配置的种子数据,会在context.Database.EnsureCreated()执行时自动写入数据库——也就是测试构造函数中创建上下文并调用EnsureCreated的时候,这些Customer种子数据就已经被插入到内存库中了。所以数据库里本来就存在这些种子数据,结果视图显示它们是符合预期的。

调试器里只看到你添加的BookInventory,是因为调试时查看的是当前上下文跟踪的实体,而种子数据是在之前的上下文实例中插入的,当前上下文未跟踪这些种子实体,所以看不到,但数据库里实际是存在的。

切换为文件型SQLite数据库的方法

完全可以,只需要修改测试构造函数里的连接字符串即可:

  1. 把内存库连接字符串"datasource=:memory:"改成文件路径,比如"Data Source=./TestBookStore.db"(相对路径,会生成在测试项目的输出目录下)。
  2. 文件型SQLite会自动管理连接,所以可以去掉_connection.Open()这行代码,调整后的构造函数如下:
public BookingServicesTests()
{
    _options = new DbContextOptionsBuilder()
        .UseSqlite("Data Source=./TestBookStore.db")
        .Options;
    using (var context = new ApplicationDBContext(_options))
    {
        // 每次测试都生成全新数据库,先删除旧文件再创建
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();
    }
}

这样每次测试运行时,都会先删除旧的测试数据库文件,再创建新的,保证测试环境干净。之后你可以用SQLite查看工具(比如DB Browser for SQLite)打开生成的TestBookStore.db文件,直接查看所有表的数据。

内容的提问来源于stack exchange,提问作者dotnetdevcsharp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:34:54