[英]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 .您还可以通过查看以下问题here和here找到一些线索。
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 中同时使用
done
和async/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/catch
与async/await
使用,就像您通常将它与同步代码一起使用一样。
Following are the most basic Mocha tests with both async/await
and done
approaches testing the same basic HTTP server endpoint.以下是最基本的 Mocha 测试,使用
async/await
和done
方法测试相同的基本 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.