Вместо заглушки then
лучше всего заглушить g
таким образом, чтобы он устанавливал логическое значение на следующей итерации цикла событий.Затем вы можете проверить это логическое значение после вызова f
, чтобы убедиться, что f
его ожидало:
it('should call g', async () => {
const x = new X();
let gFinished = false;
sinon.stub(x, 'g').callsFake(() => {
return new Promise((resolve) => {
setImmediate(() => {
gFinished = true;
resolve();
});
});
});
await x.f(10);
x.g.should.be.calledWith(10);
gFinished.should.be.true();
});
Редактировать: Конечно, это не идеальная гарантия, потому чтовы могли бы f
ждать любого обещания, которое ожидает, по крайней мере, столько времени, сколько требуется для g
разрешения.Примерно так:
async f(n) {
this.g(n);
await new Promise((resolve) => {
setImmediate(() => {
resolve();
});
});
}
Это может привести к тому, что тест, который я написал, будет пройден, хотя он все еще неверен.Так что на самом деле все сводится к тому, насколько строго вы пытаетесь быть со своими тестами.Вы хотите, чтобы было буквально невозможно иметь ложный положительный результат?Или это нормально, если какой-то очевидный обман может потенциально скинуть его?
В большинстве случаев я считаю, что с последним все в порядке, но на самом деле это зависит от вас и / или вашей команды.