简体   繁体   English

在 mocha、chai 中使用 await/async

[英]Using await / async with mocha, chai

I'm quite new to node and express.我对节点和表达很陌生。 And have been trying to write test code using mocha, chai and chai-http.并且一直在尝试使用 mocha、chai 和 chai-http 编写测试代码。 Here's the part of source code.这是源代码的一部分。

const mongoose = require('mongoose'),
  User = require('../../models/user');

const mongoUrl = 'mongodb://xxxxxxxxxxx';

describe('/test', function() {
  before('connect', function() {
    return mongoose.createConnection(mongoUrl);
  });

  beforeEach(async function(done) {
    try {
      await User.remove({}); // <-- This doesn't work
      chai.request('http://localhost:3000')
        .post('/api/test')
        .send(something)
        .end((err, res) => {
          if (err) return done(err);
          done();
        });
    } catch (error) {
      done(error);
    }
  });
});

And I get the following error with "npm test"(nyc mocha --timeout 10000 test/**/*.js).我在“npm test”(nyc mocha --timeout 10000 test/**/*.js)中得到以下错误。

Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

I confirmed the database connection works properly from log.我从日志中确认数据库连接正常工作。 And seems I get the timeout error with await User.remove({}).似乎我收到了 await User.remove({}) 的超时错误。 I've also tried different methods such as a User.save() But, I got the same error.我也尝试过不同的方法,例如 User.save() 但是,我遇到了同样的错误。 Do I need to do something special with database model and connection?我需要对数据库模型和连接做一些特别的事情吗?

I had the same problem and have not found a way to get any promises that involve mongoose working with Mocha/Chai. 我遇到了同样的问题,还没有找到一种方法来获得任何涉及mongoose与 Mocha/Chai 合作的承诺。

What may help you is doing what I did and putting your mongoose code in a script so you can run it with node <scriptfile>.js .可以帮助您的是做我所做的并将您的猫鼬代码放入脚本中,以便您可以使用node <scriptfile>.js运行它。 You can use that to confirm it's working properly by itself.您可以使用它来确认它本身是否正常工作。 In my test, the mongoose operation finished in less than a second.在我的测试中,猫鼬操作在不到一秒钟的时间内完成。 You can also call that file from another (non-test related) to confirm it executes properly and returns a promise.您还可以从另一个(非测试相关的)调用该文件以确认它正确执行并返回一个承诺。 You can see from my example how to make sure you close db properly.您可以从我的示例中看到如何确保正确关闭 db。 Partial example:部分示例:

  ...
  db.close();

  return new Promise((resolve) => {
    db.on('disconnected', () => {
      console.log('***************************************Mongoose CONNECTION TERMINATED');
      resolve('user ready');
    });
  });
  ...

You may also find some clues by looking at the following issues here and here .您还可以通过查看以下问题herehere找到一些线索。

The work around that I did after wasting too much time trying to figure out this crazy behavior was to perform my mongoose needs in a route.在浪费了太多时间试图找出这种疯狂的行为之后,我所做的工作是在路线中执行我的猫鼬需求。 I wrap each request that needs to use it in the end block of the extra chai.request... or use async.我将需要使用它的每个请求包装在额外的chai.request...end块中chai.request...或使用异步。 Example:例子:

describe('something', () => {
  it('should do something and change it back', async () => {
    try {
      // change user password
      let re1 = await chai.request(app)
        .post('/users/edit')
        .set('authorization', `Bearer ${token}`)
        .send({
          username: 'user@domain.com',
          password: 'password6',
        });
      expect(re1.statusCode).to.equal(200);

      // change password back since before hook not working
      let re2 = await chai.request(app)
        .post('/users/edit')
        .set('authorization', `Bearer ${token}`)
        .send({
          username: 'user@domain.com',
          password: 'password6',
          passwordNew: 'password',
          passwordConfirm: 'password',
        });
      expect(re2.statusCode).to.equal(200);
    } catch (error) {
      // error stuff here
    }
  });

Note that using the try/catch syntax above will cause test that should normally fail to show passing and the results will be caught in the catch block.请注意,使用上面的try/catch语法将导致通常应该无法显示通过的测试,并且结果将被捕获在 catch 块中。 If you want to avoid that, just remove the try/catch .如果您想避免这种情况,只需删除try/catch

This is all pretty simple.这一切都很简单。

To avoid the error you must not use both done and async/await in Mocha at the same time.为避免该错误,您不能在 Mocha 中同时使用doneasync/await Either use async/await and remove both done as function parameter and done() call.要么使用async/await并删除done作为函数参数和done()调用。 Or use done .或者使用done Then remove both async/await .然后删除两个async/await See example test below for both.请参阅下面的示例测试。

Use try/catch with async/await as you would normally use it with synchronous code.try/catchasync/await使用,就像您通常将它与同步代码一起使用一样。

Following are the most basic Mocha tests with both async/await and done approaches testing the same basic HTTP server endpoint.以下是最基本的 Mocha 测试,使用async/awaitdone方法测试相同的基本 HTTP 服务器端点。

This is async/await approach.这是async/await方法。

it('with async/await', async function() {
    const res = await chai.request(server)
        .get('/')
        .send();
    assert.equal(res.status, 200);
});

This is done approach.这是done方法。

it('with done & callbacks', (done) => {
    chai.request(server)
        .get('/')
        .end((err, res) => {
            assert.equal(res.status, 200);
            done();
        });
});

See the full test file snippet .查看完整的测试文件片段

For working example additionally spin basic Express server as the tests counterpart in src/app.js .对于工作示例,另外旋转基本 Express 服务器作为src/app.js的测试对应物。

See Chai HTTP plugin docs for more info on what you can do with request testing.请参阅Chai HTTP插件文档,了解有关请求测试可以做什么的更多信息。

This is it.就是这个。

How did you implement ./models/user ?你是如何实现./models/user await only works if User.remove() returns a promise, not if it expects a callback. await仅在User.remove()返回承诺时才有效,如果它需要回调则无效。 I would add debug information to your User.remove() function to see where it gets stuck.我会将调试信息添加到您的User.remove()函数中,以查看它卡在何处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 Mocha / Chai 和 async/await 验证是否引发了异常 - Verify that an exception is thrown using Mocha / Chai and async/await 使用 mocha 和 chai 进行单元测试 async/await javascript - Unit testing async/await javascript with mocha and chai 使用typescript,Mocha,Chai和SuperTest对async / await节点api函数使用nodeJs运行或调试集成测试 - Run or Debug integration test with nodeJs using typescript, Mocha, Chai and SuperTest for async/await node api-functions 异步等待 Node.js 使用 Chai 和 mocha 进行单元测试代码 - Async await Node.js Unit Testing code using Chai and mocha Node / Mocha / Chai / Sinon-异步等待单元测试错误 - Node / Mocha / Chai / Sinon - Async await unit test error Chai 没有使用 async/await 捕获抛出的错误 - Chai not catching thrown error using async/await 如何在异步等待中强制通过测试用例 Node.js 使用 Chai 和 mocha 的单元测试代码 - How to pass test-case forcibly in Async await Node.js Unit Testing code using Chai and mocha 在带有 supertest 的 mocha 断言中使用异步等待函数 - using async await function in mocha assertion with supertest 使用 Mocha、Chai、node.js 测试异步方法 - Testing async methods using Mocha, Chai, node.js Mocha与Chai HTTP异步测试? - Mocha with Chai HTTP async testing?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM