gpt4 book ai didi

node.js - 使用 knex 和 sqlite3 的 node.js 方法测试永远不会停止

转载 作者:行者123 更新时间:2023-11-28 21:15:40 25 4
gpt4 key购买 nike

我想做什么

我正在尝试测试一个使用 knexnode.js 函数。

不只是模拟 knex,我认为在内存数据库上实际运行测试很有趣,这使得这个测试不是严格单一的,但对我来说,这是唯一有用的方法测试一个 repository 类。

这也是这里投票最多的答案:https://stackoverflow.com/a/32749601/1187067

我在测试中使用了什么

  • 基于 knex
  • 的简化图书存储库 bookRepo.js
  • 测试 bookRepo.test.js 注入(inject)一个基于 SQLite3knex 连接。

问题

数据库初始化良好,测试成功,afterEach() 函数调用正常,但过程永不结束,这对管道来说尤其成问题。

我发现停止进程的唯一方法是在 bookRepo.js 和 bookRepo.test.js 中调用 knex.destroy(),但不可能销毁 knex,因为它赢了可以多次使用它。

感谢您的帮助!

代码

bookRepo.js

const knex = require('connection'); // dependency not injected in constructor

const TABLE = 'books';

class BookRepo {
constructor() {
this.knex = knex;
}

static getTable() {
return TABLE;
}

async getTitleById(id) {
const book = await this.knex(TABLE)
.select('title')
.where('id', id)
.first();

return book.title;
}
}

module.exports = BookRepo;

bookRepo.test.js

const { assert } = require('chai');
const mock = require('mock-require');
const {
describe,
it,
before,
after,
beforeEach,
afterEach,
} = require('mocha');

const sqliteConf = {
client: 'sqlite3',
connection: {
filename: ':memory:',
},
useNullAsDefault: true,
};
const knex = require('knex')(sqliteConf);

const booksTable = BookRepo.getTable();
const BOOK_1 = {
id: 1,
title: 'Batman',
};

let bookRepo;

describe('getTitleById', () => {
before(() => {
// To use sqlite3 in the tested module, replace knexfile (required by connections)
mock('../knexfile', {
development: sqliteConf,
});

// as knex is not injected in constructor, we need to require BookRepo after having mocked knexfile.
const BookRepo = require('../bookRepo');
bookRepo = new BookRepo();
});

after(() => {
mock.stopAll();
knex.destroy(); // destroys only the connection of the test, not in bookRepo
});

/**
* We initialize the SQLite database before each test (create table and insert)
*/
beforeEach(async () => {
// drop table
await knex.schema.dropTableIfExists(booksTable);

// create table
await knex.schema.createTable(booksTable, (table) => {
table.integer('id');
table.string('title');
});

// Insertion
await knex.transaction((t) => knex(booksTable)
.transacting(t)
.insert(BOOK_1)
.then(t.commit)
.catch(t.rollback))
.catch((e) => {
console.error(e);
throw new Error('failed to insert test data');
});
});

/**
* We drop the SQLite table after each test
*/
afterEach(async () => {
await knex.schema.dropTableIfExists(booksTable); // table well dropped
});

it('returns the title of the given book', async () => {
const bookRepo = new BookRepo();

const expectedTitle = BOOK_1.title;
const retrievedTitle = await bookRepo.getTitleById(BOOK_1.id);

assert.equal(retrievedTitle, expectedTitle); // OK
});
});

package.json


dependencies": {
"knex": "^0.20.1",
},
"devDependencies": {
"chai": "latest",
"mocha": "^6.2.2",
"sqlite3": "latest",
}
}

最佳答案

由于您使用的是 mocha,因此最好使用 Mocha 的 after hook并从那里调用 destroy。同样,您可以在 before 中实例化 Knex。我想不出您需要在非测试代码中调用 destroy 的原因。

关于node.js - 使用 knex 和 sqlite3 的 node.js 方法测试永远不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651587/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com