Я, конечно, могу сказать, что ничего подобного не существует в sinon или sinon-chai.
Это сложность, связанная с тестированием любой функции, основанной на обещаниях, в которой результат не используется. Если результат используется, вы знаете, что обещание должно быть выполнено, прежде чем приступить к указанному результату. Если это не так, то все становится более сложным и выходит за рамки того, что может сделать для вас sinon с помощью простой заглушки.
Наивный подход состоит в том, чтобы заглушить действие фальшивкой, которая устанавливает некоторую переменную (локально для вашего теста), чтобы отслеживать статус. Вот так:
let actionComplete = false;
const actionStub = sinon.stub(someAction).callsFake(() => {
return new Promise((resolve) => {
setImmediate(() => {
actionComplete = true;
resolve();
});
});
});
expect(actionStub).to.have.been.calledWith();
expect(actionComplete).to.be.true;
Конечно, проблема здесь в том, что ожидание любого обещания, не обязательно именно этого, пройдет этот тест, поскольку переменная будет установлена на следующемшаг цикла обработки событий, независимо от того, что заставило вас ждать следующего шага.
Например, вы можете выполнить этот проход с помощью чего-то подобного в тестируемом коде:
someAction();
await new Promise((resolve) => {
setImmediate(() => resolve());
});
Более надежный подход заключается в создании двух отдельных тестов. Тот, где обещание разрешается, и тот, где обещание отвергается. Вы можете проверить, чтобы убедиться, что отклонение вызывает отклонение содержащейся функции с той же ошибкой, которая была бы невозможна, если бы это конкретное обещание не было await
ed.
const actionStub = sinon.stub(someAction).resolves();
// In one test
expect(actionStub).to.have.been.calledWith();
// In another test
const actionError = new Error('omg bad error');
actionStub.rejects(actionError);
// Assuming your test framework supports returning promises from tests.
return functionUnderTest()
.then(() => {
throw new Error('Promise should have rejected');
}, (err) => {
expect(err).to.equal(actionError);
});
Некоторые библиотеки утверждений и расширения (может быть, как и обещал) может быть способ убрать использование обессоленных обещаний там. Я не хотел думать слишком много об инструментах, которые вы используете, и просто пытался убедиться, что идея дойдет до вас.