res.body在此使用supertest和Node.js的测试中为空
我正在用测试Node.js API,无法解释为什么res.body在此使用supertest和Node.js的测试中为空,node.js,mocha.js,supertest,Node.js,Mocha.js,Supertest,我正在用测试Node.js API,无法解释为什么res.body对象超集返回为空。数据显示在res.text对象中,但不在res.body中,您知道如何解决这个问题吗 我正在使用Express和正文解析器: app.use(bodyParser.json()); app.use(bodyParser.json({ type: jsonMimeType })); app.use(bodyParser.urlencoded({ extended: true })); 以下是我正在测试的API方法
res.body
对象超集返回为空。数据显示在res.text
对象中,但不在res.body
中,您知道如何解决这个问题吗
我正在使用Express和正文解析器
:
app.use(bodyParser.json());
app.use(bodyParser.json({ type: jsonMimeType }));
app.use(bodyParser.urlencoded({ extended: true }));
以下是我正在测试的API方法:
app.get(apiPath + '/menu', function(req, res) {
var expiration = getExpiration();
res.set({
'Content-Type': jsonMimeType,
'Content-Length': jsonTestData.length,
'Last-Modified': new Date(),
'Expires': expiration,
'ETag': null
});
res.json({ items: jsonTestData });
}
以下是我针对此API方法执行的测试:
describe('GET /menu', function() {
describe('HTTP headers', function() {
it('responds with the right MIME type', function(done) {
request(app)
.get(apiPath + '/menu')
.set('Accept', 'application/vnd.burgers.api+json')
.expect('Content-Type', 'application/vnd.burgers.api+json; charset=utf-8')
.expect(200, done);
});
it('responds with the right expiration date', function(done) {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(0,0,0,0);
request(app)
.get(apiPath + '/menu')
.set('Accept', 'application/vnd.burgers.api+json; charset=utf-8')
.expect('Expires', tomorrow.toUTCString())
.expect(200, done);
});
it('responds with menu items', function(done) {
request(app)
.get(apiPath + '/menu')
.set('Accept', 'application/vnd.burgers.api+json; charset=utf-8')
.expect(200)
.expect(function (res) {
console.log(res);
res.body.items.length.should.be.above(0);
})
.end(done);
});
});
});
我收到的失败:
1) GET /menu HTTP headers responds with menu items:
TypeError: Cannot read property 'length' of undefined
at /Users/brian/Development/demos/burgers/menu/test/MenuApiTest.js:42:25
at Test.assert (/Users/brian/Development/demos/burgers/menu/node_modules/supertest/lib/test.js:213:13)
at Server.assert (/Users/brian/Development/demos/burgers/menu/node_modules/supertest/lib/test.js:132:12)
at Server.g (events.js:180:16)
at Server.emit (events.js:92:17)
at net.js:1276:10
at process._tickDomainCallback (node.js:463:13)
最后,这里是console.log(res)
结果的摘录:
根据下面的测试,您期望“application/vnd.burgers.api+json;内容类型为charset=utf-8':
request(app)
.get(apiPath + '/menu')
.set('Accept', 'application/vnd.burgers.api+json')
.expect('Content-Type', 'application/vnd.burgers.api+json; charset=utf-8')
.expect(200, done);
此快速路由还显示将标头设置为某个自定义值JSONMMETYPE:
app.get(apiPath + '/menu', function(req, res) {
var expiration = getExpiration();
res.set({
'Content-Type': jsonMimeType,
'Content-Length': jsonTestData.length,
'Last-Modified': new Date(),
'Expires': expiration,
'ETag': null
});
res.json({ items: jsonTestData });
}
如果是这种情况,supertest不会为您自动解析JSON。内容类型标头必须以字符串“application/json”开头。如果您无法做到这一点,那么您必须自己使用JSON.parse函数将该文本字符串转换为对象
supertest用于确定是否发送json。在幕后,supertest实际上会启动您的express服务器,通过HTTP发出一个请求,然后快速关闭它。在HTTP切换之后,HTTP请求的客户端(基本上是)不知道关于“application/vnd.burgers.api+json”的服务器配置;字符集=utf-8'。它所知道的只是它通过标题(在本例中为内容类型)告诉的内容
另外,我在我的机器上尝试了你的自定义标题,我也得到了一个空的主体
编辑:更新了注释中所述的表链接这是旧的,但它帮助了我,因此我认为我可以分享一些知识 以mattr为例,我发现这些信息实际上在res.text中,而不是res.body中 我最后添加了一些特殊处理:
if(res.headers['content-type'] == 'myUniqueContentType' && res.body===undefined){
res.body = JSON.parse(res.text);
}
我的问题是
.set()
方法设置请求头,而.send()
将使用您指定的json数据设置请求体
request("/localhost:3000")
.post("/test")
.type("json")
.set({color: "red"}) //this does nothing!
.expect(200)
.end(function(res) {
done();
});
修复方法:
request("/localhost:3000")
.post("/test")
.type("json")
.send({color: "red"}) //fixed!
.expect(200)
.end(function(res) {
done();
});
加
这将接受所有json内容类型:-)我不知道该测试框架,但我的问题是,当您在console.log(res)时,res到底是什么?看起来它只是数组的字符串表示形式。因此,JSON.parse(res).
res
可能是请求的响应对象结果。超级测试只是将响应对象传递给回调函数。您正在使用res.json()序列化响应,对吗?expect函数的api声明它需要一个字符串、regex或解析的body对象是的,我正在序列化响应。但是您引用的expect(body,[fn])
不是我正在使用的方法。我使用.expect(函数(res){})
。此方法的文档说明:“传递自定义断言函数。它将被赋予要检查的响应对象。如果响应正常,它应该返回falsy,最常见的是不返回任何内容。如果检查失败,则抛出错误或返回真实值,就像字符串一样,将变成错误。”。谢谢@mattyice!正是这样,我正在为API使用自定义内容类型,并解析JSON。您链接到的表不再存在,因为节点mime
已切换为使用mime db
作为其mime类型数据。你可以找到JSON数据。到我下来的时候?如果您在使用JSON API等内容类型时遇到问题,可以这样设置。我没有投反对票,但可能是因为问题是关于supertest解析的响应体,而此更改将影响node.js服务器对请求体的解析。
request("/localhost:3000")
.post("/test")
.type("json")
.send({color: "red"}) //fixed!
.expect(200)
.end(function(res) {
done();
});
app.use(bodyParser.json({ type: 'application/*+json' }))