Почему я получаю "Ошибка: метод разрешения превышен"?
После обновления Mocha не может даже запустить простой тест, вот код
const assert = require('assert');
it('should complete this test', function (done) {
return new Promise(function (resolve) {
assert.ok(true);
resolve();
})
.then(done);
});
Я взял этот код из здесь
Я понял, что теперь он выдает исключение Error: Resolution method is overspecified. Specify a callback * or * return a Promise; not both.
Но как заставить его работать? Я не понимаю. У меня
node -v 6.9.4
mocha -v 3.2.0
Как запустить этот код теперь в новом и правильном формате?
Ответы
Ответ 1
Просто нажмите
.then(done);
и замените function(done)
на function()
Вы возвращаете Promise, так что вызов завершен, лишний, как сказано в сообщении об ошибке
В старших версиях вам приходилось использовать обратный вызов в случае таких асинхронных методов, как
it ('returns async', function(done) {
callAsync()
.then(function(result) {
assert.ok(result);
done();
});
})
Теперь у вас есть альтернатива возврата обещания
it ('returns async', function() {
return new Promise(function (resolve) {
callAsync()
.then(function(result) {
assert.ok(result);
resolve();
});
});
})
Но использование обоих является вводящим в заблуждение
(см. здесь здесь https://github.com/mochajs/mocha/issues/2407)
Ответ 2
Мокко позволяет использовать обратный вызов:
it('should complete this test', function (done) {
new Promise(function (resolve) {
assert.ok(true);
resolve();
})
.then(done);
});
ИЛИ верните обещание:
it('should complete this test', function () {
return new Promise(function (resolve) {
assert.ok(true);
resolve();
});
});
// Or in the async manner
it('should complete this test', async () => {
await Promise.resolve();
assert.ok(true);
});
Вы не можете сделать оба.
Ответ 3
У меня была такая же проблема. Много раз Mocha соединяется с другой библиотекой под названием Chai. У Чая есть посылка, которая называется "Чай как обещано". Это дает вам супер простую возможность писать меньше кода и тестировать обещания. В вашем случае просто проверить, разрешается ли обещание, оно кажется идеальным.
const chai = require('chai');
const chaiAsPromised = require("chai-as-promised");
const should = require("chai").should();
chai.use(chaiAsPromised);
describe("Testing with correct syntax and non repeated names", () => {
it("Should give us a positive response", () => {
graphQL.sendToGQL(model,"specialEndpoint").should.eventually.be.an("Object");
})
})
Ответ 4
Мне пришлось удалить done
из параметра функции и done()
вызова функции
Перед
before(async function (done) {
user = new User({ ...});
await user.save();
done()
});
После того, какAfter
before(async function () {
user = new User({ ...});
await user.save();
});
Это работает для меня
Ответ 5
Если у вас нет обратных вызовов, предыдущие ответы (которые предлагают удалить done
) верны.
Если вам нужно и дождаться какого-то внешнего обещания, а затем применить в тесте реализацию на основе callback/errback, то это решение вам не поможет.
Вы можете использовать библиотеку, такую как pify
, чтобы преобразовать API обратного вызова для использования обещаний.
Кроме того, вы можете использовать Latch
в вашем обратном вызове:
it("test", async () => {
const l = new Latch()
const v = await promiseValue()
s.methodThatTakesCallback((err, result) => {
expect(result).to.eql(expected)
l.resolve() // < notifies mocha your test is done
})
return l.promise
})
В TypeScript здесь очень упрощенная реализация Latch:
/**
* Simple one-count concurrent barrier
*/
export class Latch {
readonly promise: Promise<void>
resolve!: () => void
constructor() {
this.promise = new Promise<void>(resolve => (this.resolve = resolve))
}
}