什么是种子内存中的Sqlite数据库的推荐方法?

lawou6xi  于 12个月前  发布在  SQLite
关注(0)|答案(2)|浏览(110)

我试图在我的C#应用程序上实现一个内存中的Sqlite数据库,以用于测试目的。我想在启动过程中对数据库进行种子处理,这样我就可以控制Cypress端到端测试中使用的数据。从我在网上的研究中,我看到了两种方法来做到这一点。
第一种是使用DbContext.AddRange()方法将数据添加到上下文,如Mircosoft的示例所示。
第二个是在OnModelCreating()方法中,您可以像这样将数据添加到模型中:

modelBuilder.Entity<Book>().HasData(
    new Book { BookId = 1, AuthorId = 1, Title = "Hamlet" },
    new Book { BookId = 2, AuthorId = 1, Title = "King Lear" },
    new Book { BookId = 3, AuthorId = 1, Title = "Othello" }
);

Microsoft上的文档:https://learn.microsoft.com/en-us/ef/core/modeling/data-seeding
在这两种情况下,我相信你也必须使用context.Database.EnsureCreated();,但我不确定把它放在哪里。
推荐的方法是什么?

omjgkv6w

omjgkv6w1#

从测试的Angular 来看,内存中似乎是一个限制因素,因为Cypress不能直接与EF纯粹在其内存空间中创建的数据库进行互操作。
但是您可以通过node-sqlite3创建一个基于文件的Sqlitedb,您可以通过调用Cypress任务来播种它。
这里有一个示例配方server-communication__seeding-database-in-node
cypress.config.js中设置了cy.task('seed:db')

const { defineConfig } = require('cypress')

const { seed } = require('./server/db')

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://localhost:7082',
    supportFile: false,
    setupNodeEvents (on, config) {
      on('task', {
        'seed:db' (data) {
          return seed(data).then(() => {
            return data
          })
        },
      })
    },
  },
})

例如,在Cypress配方中,./server/db.js将需要来自node-sqlite3包的一些代码,而不是它当前拥有的代码(使用json文件作为数据库)。

const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');

db.serialize(() => {
    db.run("CREATE TABLE lorem (info TEXT)");

    const stmt = db.prepare("INSERT INTO lorem VALUES (?)");
    for (let i = 0; i < 10; i++) {
        stmt.run("Ipsum " + i);
    }
    stmt.finalize();

    db.each("SELECT rowid AS id, info FROM lorem", (err, row) => {
        console.log(row.id + ": " + row.info);
    });
});

db.close();

您的测试可能需要另一个任务来在测试流的某些点创建/更新/删除数据库记录。您应该能够调整上述代码来处理此问题。

yks3o0rb

yks3o0rb2#

我试图在我的C#应用程序上实现一个内存中的Sqlite数据库,以用于测试目的。
由于目标是使用应用程序进行单元测试,因此要使用HasData方法,您需要创建一个从应用程序上下文继承的类(或者您将在实际上下文中拥有种子数据)。
此外,HasData是一种更有限的方法,因为数据被应用于测试的所有上下文示例。这可能是有意义的,但有一些共享数据用于所有情况,但我个人倾向于通过一些共享方法(将执行AddRangeSaveChanges)引入这些数据,这些方法在某种one time setup中被调用(取决于所使用的测试框架),这是一种更灵活的方法,并允许更细粒度的控制。
还有一件事,我建议研究-使用testcontainers进行此类测试,而不是内存中的SQLite,即。启动数据库容器根据需要设置并使用它,这将通过使用特定数据库服务器产生更相关的测试结果。

相关问题