TLDR:我的api可以很好地与curl和postman配合使用,但在一个put请求中使用chai-http时(所有其他put请求都可以工作),测试失败,出现错误“Cannot set headers after they are sent to the client”。我有一个针对我所有集合的通用更新方法(见下文),它适用于其他更新/放置请求。谢谢你的帮助。
摩卡
process.env.NODE_ENV = 'test';
const chai = require('chai');
const chaiHttp = require('chai-http');
const expect = chai.expect;
const c_paths = require('../constants/paths.js');
const app = require('../app.js');
chai.use(chaiHttp);
describe(c_paths.clients, () => {
it('It should create a new clients document', done => {
let req = {
test: true,
data: [
{
name: 'client 1',
contacts: [
{
name: 'client name 1',
mobile: 'client mobile 1',
email: 'client1@email.com',
},
],
address: ['client address 1'],
},
],
};
chai
.request(app)
.post(c_paths.clients)
.send(req)
.end((err, res) => {
expect(res).to.have.status(200);
expect(res.body.insertedCount).is.equal(
1,
'Number of inserted documents.',
);
expect(res.body.ops[0].name).is.equal(req.data[0].name);
expect(res.body.ops[0].contacts[0].name).is.equal(
req.data[0].contacts[0].name,
);
expect(res.body.ops[0].contacts[0].mobile).is.equal(
req.data[0].contacts[0].mobile,
);
expect(res.body.ops[0].contacts[0].email).is.equal(
req.data[0].contacts[0].email,
);
expect(res.body.ops[0].address[0]).is.equal(req.data[0].address[0]);
expect(res.body.ops[0].pause_updates).is.false;
expect(res.body.ops[0].pause_updates_toggle).is.false;
done();
});
});
it.('It should add a reccuring job', done => {
let req = {
test: true,
filter: {
name: 'client 1',
},
set: {
recurring_jobs: [
{
job_id: 'job id 1',
current_employee_id: 'employee id 1',
employee_scheduled_till: 'Apr 30 2019',
notes: ['note 1'],
duties: ['duty 1'],
repeat_in_days: 7,
time: '11:00:00', // Validation error switched to 10000
start_date: 'Mar 01 2019',
end_date: 'May 30 2019',
is_active: true,
},
],
},
};
chai
.request(app)
.put(c_paths.clients)
.send(req)
.end((err, res) => {
expect(res).to.have.status(200);
expect(res.body.ok).is.equal(1);
done();
});
});
it('It should delete one document', done => {
let req = {
test: true,
filter: {
name: 'client 1',
},
};
chai
.request(app)
.delete(c_paths.clients)
.send(req)
.end((err, res) => {
expect(res).to.have.status(200);
expect(res.body.n).is.equal(1, 'Number of documents removed');
done();
});
});
});
在中更新方法。/routes/crud.js .第131行的错误是RES . status(200)send(result);
function update(req, res, dbName, collectionName, joiSchema) {
var toValidate = '[';
var data = '{';
if (req.body.set) {
toValidate = toValidate.concat(JSON.stringify(req.body.set), ',');
data = data.concat('"$set":', JSON.stringify(req.body.set), ',');
}
if (req.body.inc) {
toValidate = toValidate.concat(JSON.stringify(req.body.inc), ',');
data = data.concat('"$inc":', JSON.stringify(req.body.inc), ',');
}
if (req.body.addToSet) {
let temp = JSON.stringify(req.body.addToSet);
temp = temp.replace('{"$each":[', '[');
temp = temp.slice(0, -1); // Removes $each for validation
toValidate = toValidate.concat(temp, ',');
data = data.concat('"$addToSet":', JSON.stringify(req.body.addToSet), ',');
}
if (req.body.unset) {
data = data.concat('"$unset":', JSON.stringify(req.body.unset), ',');
}
if (req.body.currentDate) {
toValidate = toValidate.concat(JSON.stringify(req.body.currentDate), ',');
data = data.concat(
'"$currentDate":',
JSON.stringify(req.body.currentDate),
',',
);
}
if (req.body.rename) {
data = data.concat('"$rename":', JSON.stringify(req.body.rename), ',');
}
if (req.body.pullAll) {
toValidate = toValidate.concat(JSON.stringify(req.body.pullAll), ',');
data = data.concat('"$pullAll":', JSON.stringify(req.body.pullAll), ',');
}
toValidate = toValidate.slice(0, -1); // Removes trailing comma
data = data.slice(0, -1);
toValidate = toValidate.concat(']');
data = data.concat('}');
Joi.validate(toValidate, joiSchema, function(err, value) {
if (err) {
res.send(err);
return;
}
});
MongoClient.connect(c_db.url, function(err, db) {
if (err) {
res.send(err);
db.close();
return;
}
const dbo = db.db(dbName);
const filter = req.body.filter == null ? '' : req.body.filter;
dbo
.collection(collectionName)
.updateMany(filter, JSON.parse(data), function(err, result) {
if (err) {
res.send(err);
db.close();
return;
}
res.status(200).send(result); //Error Line 131
db.close();
});
});
};
错误响应
错误[ERR_HTTP_HEADERS_SENT]:在将标头发送到ServerResponse处的客户端后,无法设置标头。ServerResponse上的setHeader(_http_outgoing.js:482:11)。ServerResponse上的header(./App/node_modules/express/lib/response.js:767:10)。在ServerResponse发送(./App/node_modules/express/lib/response.js:170:12)。ServerResponse上的json(./App/node_modules/express/lib/response.js:267:15)。发送(./App/node_modules/express/lib/response.js:158:21),位于./App/routes/crud。js:131:25在会话的结果(./App/node_modules/mongodb/lib/utils.js:414:17)。客户端会话的endSession(./App/node_modules/mongodb/lib/utils.js:401:11)。executeCallback(./App/node_modules/mongodb-core/lib/sessions.js:129:41)的endSession(./App/node_modules/mongodb/lib/utils.js:397:17)
这是一个Joi验证错误,为了解决它,我将JSON.stringify(req.body)添加到expect错误或console.log中,即expect(res.body.n,JSON . stringify(req . body)is . equal(1);
这给了我在Mocha测试中的验证错误,一旦修复它就可以正常工作了。
问题内容: 我不太确定为什么会收到此错误。这是一个基于express.js的简单API,能够添加和删除帖子。当我触发删除路由器时发生错误。我读到错误通常在有两个回调的情况下发生,但是,我似乎找不到任何双重回调。 这是我的posts.js路由器: 问题答案: 您需要添加“返回”,这样您就不会再次回答。
问题内容: 我对Node.js相当陌生,遇到了一些问题。 我正在使用Node.js 4.10和Express 2.4.3。 当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将重定向到http://127.0.0.1:8888/auth/facebook_callback。 然后,我收到以下错误: 以下是我的代码: 我可以知道我的代码有什么问题吗? 问题答案:
尝试将图像上传到Azure存储blob,但fetch方法不起作用。 它在postman中工作正常,但在获取时显示错误 在赫鲁库部署中没有问题 这个代码有什么问题
问题内容: 我对Node.js相当陌生,遇到了一些问题。 我正在使用Node.js 4.10和Express 2.4.3。 当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将重定向至http://127.0.0.1:8888/auth/facebook_callback。 然后,我收到以下错误: 以下是我的代码: 我可以知道我的代码有什么问题吗? 问题答案:
所以我看到了一篇很棒的帖子“错误:发送到客户端后无法设置标题,但仍然不明白我的“标题”部分有什么问题,因为当我将它从注释掉的
如何在nodejs中发送文件,我正在创建一个页面应用程序,所以我只想abcd.html页面首次按要求交付,这是我的代码 app.js 对页面的响应 发送后,它总是给出无法设置的标题,下面是控制台输出 错误:SendStream禁止。SendStream出错(/home/pitu/CODING/NODE-PROJECTS/chichat/NODE\u modules/express/NODE\u m