我正在尝试在我的 C# 应用程序上实现内存中的 Sqlite 数据库以用于测试目的。我想在启动期间为数据库播种,以便我可以控制赛普拉斯端到端测试中使用的数据。根据我的在线研究,我发现有两种方法可以做到这一点。
第一个是使用
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();
,但我不知道该把它放在哪里。
用测试数据为我的数据库播种的推荐方法是什么?
从测试的角度来看,内存中似乎是一个限制因素,因为 Cypress 无法直接与 EF 纯粹在其内存空间中创建的数据库进行互操作。
但是您可以通过 node-sqlite3 创建基于文件的 Sqlite 数据库,您可以通过调用 Cypress 任务来播种。
这里有一个示例配方 server-communication__seeding-database-in-node
这在
cy.task('seed:db')
中设置了
cypress.config.js
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();
您的测试可能需要另一个任务来在测试流程中的某些点创建/更新/删除数据库记录。您应该能够调整上面的代码来处理这个问题。
我正在尝试在我的 C# 应用程序上实现内存中的 Sqlite 数据库以用于测试目的。
由于目标是使用应用程序进行单元测试,因此要使用
HasData
方法,您将需要创建一个从应用程序上下文继承的类(或者您将在实际上下文中拥有种子数据)。
此外,
HasData
是一种更有限的方法,因为数据被应用于测试的所有上下文实例。这是有道理的,但有一些共享数据可用于所有情况,但我个人倾向于通过某种共享方法引入此类数据(这将执行 AddRange
和 SaveChanges
),这在某种 中被称为一次性设置(取决于所使用的测试框架),这是一种更灵活的方法,并且允许对所需进行更精细的控制。
我还建议研究一件事 - 使用 testcontainers 进行此类测试而不是内存中的 SQLite,即启动数据库容器根据需要进行设置并使用它,这将通过使用产生更相关的测试结果特定的数据库服务器。
我最终选择了每次运行测试时在 Docker 容器上启动的 SQL Server DB 映像,因为 SQLite 和 Sql Server 之间存在无法克服的差异,并且它们会干扰测试。 但是如果有人想要填充 Sqlite 数据库进行测试,您可以将类似的内容添加到
Configure()
中的 Startup
方法中:
context.Database.EnsureCreated();
//call service to populate database
SqliteDbSeeder.PopulateDatabase(context);
SqliteDbSeeder.PopulateDatabase()
方法使用context.AddRange()
和SaveChanges()
将实体添加到数据库中。我实际上将它们保存在 json 文件中,将它们转换为实体,然后将它们添加到数据库中。