为什么我会收到“错误:解决方法被过度指定”?

时间:2017-01-20 10:42:17

标签: node.js mocha

升级后,Mocha甚至无法在这里运行简单的测试代码

<div data-bind="text: firstName, click: $parent.selectUser.bind($parent)">

我从here

获取了此代码

我知道它现在抛出异常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.

如何运行此代码现在采用新的正确格式?

7 个答案:

答案 0 :(得分:23)

刚下降
.then(done);并将function(done)替换为function()

你正在返回一个Promise,所以调用done是多余的,正如它在错误消息中所说的那样

在老版本中,你必须使用回调,如果是

这样的异步方法
it ('returns async', function(done) {
   callAsync()
   .then(function(result) {
      assert.ok(result);
      done();
   });
})

现在您可以选择返回Promise

it ('returns async', function() {
  return new Promise(function (resolve) {
     callAsync()
       .then(function(result) {
          assert.ok(result);
          resolve();
       });
  });
})

但使用两者都会产生误导 (例如参见https://github.com/mochajs/mocha/issues/2407

答案 1 :(得分:6)

Mocha允许使用回调:

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);
});

你不能同时做到这两点。

答案 2 :(得分:0)

我有同样的问题。很多时候,摩卡咖啡与另一个名为Chai的图书馆配对。 Chai有一个名为“ chai-as-promised”的程序包。它为您提供了编写更少代码和测试承诺的超级简单能力。在您仅测试承诺是否得以解决的情况下,这似乎是完美的。

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");
    })
})

答案 3 :(得分:0)

我不得不从函数参数中删除done和函数调用中的done() 之前

   before(async function (done) {
        user = new User({ ...});
        await user.save();
        done()
    });

之后

   before(async function () {
        user = new User({ ...});
        await user.save();
    });

这些对我有用

答案 4 :(得分:0)

如果没有回调,则先前的答案(建议删除done)是正确的。

如果需要两者都在等待一些外部承诺,然后在测试中执行基于回调/基​​于错误的实现,那么该解决方案将无济于事。

您可以使用pify之类的库来将回调API转换为使用Promise。

或者,您可以在回调中使用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))
  }
}

答案 5 :(得分:0)

一个带有中断功能的异步函数示例。

故障案例

<template v-if="boolean">
<cmp-1 />
</template>
<template v-else>
<cmp-2 />
</template>

成功案例

it('If the credentials exists in the system it should return the token generated against it.', async (done) => {
    let aObj = await admin.createAdmin();
    chai.request(server)
    .post("/authenticate")
    .set("Content-Type", "application/x-www-form-urlencoded")
    .send({username: aObj.login,password:aObj.password})
    .end((err, res) => {
        res.should.have.status(200);
        res.body.should.be.a("string");
        done();
    });
});

答案 6 :(得分:0)

只需完全发出完成的回调并改用异步。 (此实现基于在 firebase 函数上运行的 express api,使用自定义 jsonwebtoken)

const { FIREBASE_UID } = require('dotenv').config()?.parsed
const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../lib/api').API;
const should = chai.should();
const expect = chai.expect

chai.use(chaiHttp)

const test = chai.request(server).keepOpen()

// get your token with an earlier mock request and store to a var
describe('Just checking a token', () => {

 let some_token
 it('should print custom jwt for testing, status: 200'), async () => {
    try {
        const res = await test.get(`/createCustomFirebaseToken/${FIREBASE_UID}`).send()
        res.should.exist
        res.should.have.status(200);
        res.should.have.json
        some_token = (JSON.parse(res.text)).token
    } catch (error) {
        throw error
    }
}
 it('should print details:PING, status:200'), async () => {
    try {
        const res = await test.get('/').set('Authorization',`Bearer ${some_token}`)
                              .send()
        res.should.exist
        res.should.have.status(200);
        res.should.have.json
        const { details, status } = JSON.parse(res.text)
        expect(details).to.equal('PING')
        expect(status).to.equal(200)
    } catch (error) {
        throw error
    }
 }
 after(() => test.close())
})