我正在设置我的集成测试设备。我正在使用beforeEach
and afterEach
挂钩将每个测试包装在回滚的事务中,以便测试不会相互影响。一个简化的例子可能是这样的:
const { repository } = require("library")
describe("Suite", function () {
beforeEach(async function () {
await knex.raw("BEGIN");
});
afterEach(async function () {
await knex.raw("ROLLBACK");
});
it("A test", async function () {
const user = await repository.createUser()
user.id.should.equal(1)
});
});
这工作得很好,因为我将 knex 配置为使用单个数据库连接进行测试。因此调用knex.raw("BEGIN");
创建了一个global交易。
然而现在,我无法控制的图书馆的存储库开始在内部使用事务。 IE。createUser()
开始然后commits创建的用户。这打破了我的测试,就像现在我的afterEach
hook 不会回滚更改,因为它们已经提交。
Postgres 中有没有办法回滚具有(已提交)嵌套事务的事务?
或者也许有一种方法可以使用 knex 来阻止存储库首先启动事务?它用knex.transaction()
创建它们。
Thanks!
从外表来看调试日志示例 https://github.com/knex/knex/issues/3389#issuecomment-519811122,knex 实际上会自动检测事务嵌套,并将嵌套事务从使用不可逆commit
/rollback
to 易于管理的 https://www.postgresql.org/docs/current/sql-savepoint.html savepoint s1
/release s1
/rollback to s1
就像我猜测的那样我的评论 https://stackoverflow.com/questions/74387244/how-to-wrap-code-that-uses-transcations-in-a-transaction-and-then-rollback#comment131502339_74387244.
在这种情况下,您应该足以将调用包装在事务中,以便您“拥有”顶级事务。 Knex 应该检测到这一点并强制底层事务使用保存点而不是提交,然后您可以撤消所有这些操作,回滚顶级事务。如果我读the doc https://knexjs.org/guide/transactions.html right:
const { repository } = require("library")
describe("Suite", function () {
it("A test", async function () {
try {
await knex.transaction(async trx => {
const user = await repository.createUser();
user.id.should.equal(1);
trx.rollback();
})
} catch (error) {
console.error(error);
}
});
});
假设下面的调用都没有发出knex.raw("COMMIT")
或以某种方式调用.commit()
在外部、顶级交易上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)