测试API如何使用node.js处理无效的JSON语法请求主体

时间:2015-02-02 20:23:19

标签: javascript json node.js superagent frisby.js

我想测试REST API如何处理具有无效JSON语法的主体的POST请求,例如缺少逗号。我使用node.js编写API测试。我使用frisby,但我也试过了supertest。没运气。使用以前的工具,您将请求主体作为JavaScript对象传递,因此不行。我还尝试将无效的JSON作为字符串传递而没有任何运气,因为字符串也是有效的JSON(下面的示例)。有什么想法吗?

frisby.create('Ensure response has right status')
    .post('http://example.com/api/books', '{"invalid"}', {json: true})
    .expectStatus(400)
    .toss();

4 个答案:

答案 0 :(得分:4)

使用supertest和mocha包,您可以通过发布无效的JSON来测试端点,如下所示:

var request = require('supertest');

describe('Adding new book', function(){
  it('with invalid json returns a 400', function(done){
    request('http://example.com').post('/api/books')
      .send('{"invalid"}')
      .type('json')
      .expect('Content-Type', /json/)
      .expect(400)
      .end(function(err, res) {
          console.log(res.error);
          done();
      });
  });
});

这里重要的一点是type(json)。这会将请求的Content-Type设置为application / json。有了它,supertest / superagent将默认发送字符串作为application / x-www-form-urlencoded。此外,无效的JSON是作为字符串提供的,而不是JavaScript对象。

答案 1 :(得分:3)

我从未使用过Frisby或superagent,但我发现这里有两个问题:

  

<强> 1。使用POST方法将无效的JSON从客户端传递到服务器。

这是不可能的,因为它很快会在客户端本身被拒绝,并且在向服务器发出POST请求之前会收到错误。 (因为在使用http时只有字符串,客户端本身会尝试将JSON字符串化,因为它会被无效的JSON卡住)

  

<强> 2。传递无效的JSON就像一个字符串

示例:使用JQuery

POST一个这样的字符串
 $.post("demo_test_post.asp",
    {
        name: 'pqr:{"abc":"abc",}'    // see there is a comma at the end making JSON invalid
    },
    function(data, status){
        alert("Data: " + data + "\nStatus: " + status);
    });

这将有效地将无效的JSON(在本例中为名称)作为srting传递给服务器。但是这需要您使用JSON.parse()将字符串解析为JSON,然后才能使用它。当你尝试时,你会得到这个:

  

SyntaxError: Object.parse (本机)处的意外标记p   Object.app.get.res.send.data [as handle]   (/home/ubuntu/workspace/TapToBook.js:35:19)在next_layer   (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:103:13)   在Route.dispatch   (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:107:5)   在proto.handle.c   (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:195:24)   在Function.proto.process_params   (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:251:12)   在下一个   (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:189:19)   在Layer.staticMiddleware [作为句柄]   (/home/ubuntu/workspace/node_modules/express/node_modules/serve-static/index.js:55:61)   在trim_prefix   (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:226:17)   在proto.handle.c   (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:198:9)

无论您使用休息的软件包,都可以将无效的JSON作为字符串传递,但不能使用它。

答案 2 :(得分:1)

我认为您的测试需要验证服务器是否正在处理无效的JSON(并且不会崩溃)。希望能回复400个不良请求。

由于http中的POST只是一个字符串,因此测试的一个选项是使用需要您提供JSON对象的API。

如果使用原始节点http,则可以发送所需的任何无效字符串:

How to make an HTTP POST request in node.js?

还有流行的请求库。

https://github.com/request/request

例如,对于库,您的测试可能会从文件中拾取无效内容并进行发布或放置。来自他们的文档:

fs.createReadStream('file.json').pipe(request.put('http://example.com/obj.json'))

答案 3 :(得分:0)

使用npm请求库时,这实际上是一个简单的技巧。这是我取得的成就,并且正在起作用。

    describe('with invalid JSON, attempt a config api call', () => {
      let response;
      before(async () => {
        const k = "on:true";
        response = await request.put(configURL+ `/0/config/`, {
          json:k,
          headers: {
            authorization: bearer,
            "content-type": "application/json",
          }
        })
      });
      it('should return http 400 OK', () => {
        response.statusCode.should.equal(400);
      });
      it('should have error message as SyntaxError: Unexpected token in JSON body', () => {
        response.body.should.equal("SyntaxError: Unexpected token in JSON body");
      });
    });

注意:这是无效的JSON,因为ON不带引号。这将帮助测试人员使用请求库。