此测试中使用supertest和Node.js的res.body为空 [英] res.body is empty in this test that uses supertest and Node.js

查看:259
本文介绍了此测试中使用supertest和Node.js的res.body为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 supertest 测试Node.js API,但我无法解释为什么res.body对象超集返回的值为空.数据显示在res.text对象中,而不显示在res.body对象中,您知道如何解决此问题吗?

I am testing a Node.js API with supertest, and I cannot explain why the res.body object superset returns is empty. The data shows up in the res.text object, but not res.body, any idea how to fix this?

我正在使用Express和body-parser:

I am using Express and body-parser:

app.use(bodyParser.json());
app.use(bodyParser.json({ type: jsonMimeType }));
app.use(bodyParser.urlencoded({ extended: true }));

这是我正在测试的API方法:

Here is the API method I am testing:

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方法执行的测试:

Here are the tests I am executing against this API method:

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)结果的摘录:

And finally, here is an excerpt of the result of 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: {},
...

推荐答案

基于以下测试,您需要'application/vnd.burgers.api + json; charset = utf-8'作为Content-Type:

Based on the following test you are expecting 'application/vnd.burgers.api+json; charset=utf-8' as the Content-Type:

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);

这条快速路线还显示了将标头设置为一些自定义值jsonMimeType:

This express route also shows you setting the header to some custom value, 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 });
}

在这种情况下,supertest不会自动为您解析该JSON.内容类型标头必须以字符串'application/json'开头.如果您无法做到这一点,那么您将不得不自己使用JSON.parse函数将文本字符串转换为对象.

If this is the case, supertest isnt going to parse that JSON automatically for you. The content-type header must start with the string 'application/json'. If you cant make that happen, then you will have to use the JSON.parse function yourself to convert that text string to an object.

supertest使用此文件来确定您是否要发送json与否.在后台,supertest实际上会启动您的Express服务器,通过HTTP发出一个请求,然后迅速将其关闭.进行HTTP交接后,该HTTP请求的客户端(基本上是 superagent )对您的信息一无所知.关于"application/vnd.burgers.api + json"的服务器配置; charset = utf-8'.它所知道的只是通过标题(在本例中为content-type)告诉的内容.

supertest uses this file to determine if you are sending json or not. Under the hood, supertest actually starts up your express server, makes the one request via HTTP, and quickly shuts it down. After that HTTP handoff, the client side (which is basically superagent) of that HTTP request doesnt know anything about your server configuration with regard to 'application/vnd.burgers.api+json; charset=utf-8'. All it know is what its told via headers, in this case, content-type.

此外,我确实在计算机上尝试了您的自定义标头,但我也得到了一个空的正文.

Also, I did try your custom header on my machine and I also got an empty body.

修改:如注释中所述更新表格链接

updated table link as stated in the comments

这篇关于此测试中使用supertest和Node.js的res.body为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆