Почему я получаю "Ошибка: метод разрешения превышен"?

После обновления 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))
  }
}