blu*_*din 11 mocha.js node.js supertest
我正在使用supertest测试Node.js API ,我无法解释为什么res.body对象超集返回为空.数据显示在res.text对象中,但不是res.body,任何想法如何解决这个问题?
我正在使用Express和body-parser:
app.use(bodyParser.json());
app.use(bodyParser.json({ type: jsonMimeType }));
app.use(bodyParser.urlencoded({ extended: true }));
Run Code Online (Sandbox Code Playgroud)
这是我正在测试的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 });
}
Run Code Online (Sandbox Code Playgroud)
以下是我针对此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);
});
});
});
Run Code Online (Sandbox Code Playgroud)
我收到的失败:
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)
Run Code Online (Sandbox Code Playgroud)
最后,这里是以下结果的摘录console.log(res):
...
text: '{"items":[{"id":"1","name":"cheeseburger","price":3},{"id":"2","name":"hamburger","price":2.5},{"id":"3","name":"veggie burger","price":3},{"id":"4","name":"large fries","price":2},{"id":"5","name":"medium fries","price":1.5},{"id":"6","name":"small fries","price":1},{"id":"7","name":"large drink","price":2.5},{"id":"8","name":"medium drink","price":2},{"id":"9","name":"small drink","price":1}]}',
body: {},
...
Run Code Online (Sandbox Code Playgroud)
基于以下测试,您期待'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);
Run Code Online (Sandbox Code Playgroud)
此快速路由还显示您将标头设置为某个自定义值jsonMimeType:
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 });
}
Run Code Online (Sandbox Code Playgroud)
如果是这种情况,supertest将不会自动为您解析该JSON.content-type标头必须以字符串'application/json'开头.如果你无法实现这一点,那么你必须自己使用JSON.parse函数将该文本字符串转换为对象.
supertest使用此文件来确定您是否正在发送json.supertest实际启动你的快速服务器,通过HTTP发出一个请求,然后快速关闭它.在HTTP切换之后,该HTTP请求的客户端(基本上是superagent)对'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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11862 次 |
| 最近记录: |