我对节点表达很陌生。 并且一直在尝试使用mocha,chai和chai-http编写测试代码。 这是源代码的一部分。
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);
}
});
});
然后我用“ 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.
我从日志确认数据库连接正常。 似乎我在等待User.remove({})时收到超时错误。 我也尝试过其他方法,例如User.save() 但是,我遇到了同样的错误。 我需要对数据库模型和连接做一些特别的事情吗?
答案 0 :(得分:2)
I had the same problem,但尚未找到一种方法来获得涉及mongoose
与Mocha / Chai合作的任何承诺。
可能会帮助您执行我所做的事情,并将您的猫鼬代码放入脚本中,以便您可以使用node <scriptfile>.js
运行它。您可以使用它来确认它本身是否正常工作。在我的测试中,猫鼬手术不到一秒钟就完成了。您还可以从另一个文件(与测试无关的文件)中调用该文件,以确认文件是否正确执行并返回承诺。您可以从我的example中了解如何确保正确关闭数据库。部分示例:
...
db.close();
return new Promise((resolve) => {
db.on('disconnected', () => {
console.log('***************************************Mongoose CONNECTION TERMINATED');
resolve('user ready');
});
});
...
在浪费大量时间试图弄清这种疯狂行为之后,我所做的工作是在一条路线上执行我的猫鼬需求。我将每个需要使用的请求包装在额外的end
的{{1}}块中或使用异步处理。示例:
chai.request...
请注意,使用上述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
}
});
语法将导致通常无法通过测试的测试,结果将被捕获在catch块中。如果要避免这种情况,只需删除try/catch
。
答案 1 :(得分:2)
这一切都非常简单。
为避免错误,您不能同时在Mocha中同时使用done
和async/await
。使用async/await
并删除done
作为函数参数和done()
调用。或使用done
。然后删除两个async/await
。两者请参见下面的示例测试。
将try/catch
与async/await
一起使用,就像通常将其与同步代码一起使用一样。
以下是使用async/await
和done
方法测试同一基本HTTP服务器端点的最基本的Mocha测试。
这是async/await
方法。
it('with async/await', async function() {
const res = await chai.request(server)
.get('/')
.send();
assert.equal(res.status, 200);
});
这是done
方法。
it('with done & callbacks', (done) => {
chai.request(server)
.get('/')
.end((err, res) => {
assert.equal(res.status, 200);
done();
});
});
对于工作示例,请另外旋转basic Express server作为src/app.js
中的测试对象。</ p>
有关可以使用请求测试执行的操作的更多信息,请参见Chai HTTP插件文档。
就这样。
答案 2 :(得分:0)
您是如何实现./models/user
的? await
仅在User.remove()
返回promise时才有效,而不是期望回调的情况下才有效。我会将调试信息添加到您的User.remove()
函数中,以查看其卡在哪里。