gpt4 book ai didi

javascript - Mocha - 将变量从 `beforeEach` 传递到 `afterEach` 和 `it`

转载 作者:行者123 更新时间:2023-12-01 07:52:55 25 4
gpt4 key购买 nike

这个问题可以解决很多通用的解决方案,所以我会尝试用这样的方式来表达它。我有一种情况,我需要相同的 beforeEachafterEach代码块运行,但每次只需要更改一个变量(或几个)。

我的具体情况:我每次都需要从数据库中插入/删除。代码:

首先为测试设置临时表:

before(function(done) {
db.query('CREATE TEMPORARY TABLE tmp AS SELECT * FROM example_table', null, function(error) {
return done();
});
});

然后在每次测试之前/之后 Hook [编辑@luboskrnac 建议] :
var vals = []

beforeEach(init_vals, function(done) {
mysql.query('INSERT INTO tmp (a, b) VALUES (?, ?)', init_vals, function(error, rows) {
return done();
});
});

// pass values [1, 2] to `beforeEach`
it('check value is in database', function(done) {
mysql.query('SELECT * FROM tmp WHERE a = ? AND b = ?', function(error, rows) {
vals = [1, 2];
expect(rows[0].a === vals.a);
expect(rows[0].b === vals.b);
return done(); // pass values
})
})

afterEach(function(done) {
mysql.query('DELETE FROM tmp WHERE a = ? AND b = ?', vals, function(error, rows) {
return done();
});
});

然后在 session 关闭时清理(临时)表。有没有办法通过 values作为每个 it 的这些钩子(Hook)的变量测试?

最佳答案

it 是不可能的调用限制beforeEach的数据Mocha 将在 it 之前运行的 Hook 打电话会看到。 it call 可以影响在它之后运行的内容,但不会影响在它之前运行的内容。

我要做的只是将初始化代码移动到可以从测试中调用的函数中,并在每个测试中调用它。像这样的东西:

describe(function () {
// Record values we may need to clean after the test.
var to_clean;

function init(vals, cb) {
mysql.query('INSERT INTO tmp (a, b) VALUES (?, ?)', vals,
function(error, rows) {
// Record that we need to clean some values.
to_clean = vals;
cb(error);
});
}

it('check value is in database', function(done) {
var vals = [1, 2];
init(vals, function (error) {
if (error) {
done(error);
return;
}

mysql.query('SELECT * FROM tmp WHERE a = ? AND b = ?',
function(error, rows) {
if (error) {
done(error);
return;
}

// You need to catch these if you want a
// precise error report from
// Mocha. Otherwise, you get a vague
// timeout error.
try {
expect(rows[0].a === vals.a);
expect(rows[0].b === vals.b);
}
catch(e) {
done(e);
return;
}

done();
});
});
});

afterEach(function(done) {
if (to_clean) {
mysql.query('DELETE FROM tmp WHERE a = ? AND b = ?', to_clean,
function(error, rows) {
// Reset so that we don't try to clean
// obsolete data. Yes, we clear this even
// if there was an error.
to_clean = undefined;
done(error);
});
}
else {
// Nothing to clean, we're done.
done();
}
});
});

您会注意到我有一些不在您的代码中的额外错误检查。这对于确保 Mocha 以最详细的信息报告错误是必要的。我强烈建议使用返回 Promise 的库,因为它会大大简化代码。

Hooks 和共享函数的区别

Mocha 以不同的方式处理测试失败和钩子(Hook)( beforebeforeEach 等)失败。如果测试失败,Mocha 将继续执行其他测试。如果钩子(Hook)失败,Mocha 认为这是测试套件的失败,并会跳过执行任何依赖于钩子(Hook)的操作。这是一个简单的例子:
describe("top", () => {
let fail = true;
beforeEach(() => {
fail = !fail;
if (fail) {
throw new Error("fail");
}
});

it("one", () => {});
it("two", () => {});
it("three", () => {});
});

describe("top 2", () => {
it("one", () => {});
it("two", () => {});
it("three", () => {});
});

当我在上面运行 Mocha 时,我得到了这个输出:
  top
✓ one
1) "before each" hook for "two"

top 2
✓ one
✓ two
✓ three


4 passing (10ms)
1 failing

1) top "before each" hook for "two":
Error: fail
at Context.beforeEach (test2.js:6:19)

您可以在第一个 describe 中看到 block ,只运行了前两个测试。尽快 beforeEach失败,Mocha 跳过 describe 中的其余测试 block ,但第二个可以运行,因为它不依赖于失败的钩子(Hook)。

因此,当您使用共享函数而不是钩子(Hook)来初始化测试数据时,您实际上是在导致 Mocha 将初始化失败视为测试失败而不是套件失败。测试失败和套件失败之间的界线是有争议的,并且实际上取决于项目的细节。

关于javascript - Mocha - 将变量从 `beforeEach` 传递到 `afterEach` 和 `it`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40975424/

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