最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Test how API handles invalid JSON syntax request body using node.js - Stack Overflow

programmeradmin0浏览0评论

I would like to test how an REST API handles a POST request that has a body with invalid JSON syntax, for example a missing comma. I'm using node.js to write the API tests. I'm using frisby but I also tried supertest. No luck. With the previous tools, you pass the request body as a JavaScript object, so it's no go. I tried also to pass the invalid JSON as a string without any luck, since a string is also valid JSON (example below). Any ideas?

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

I would like to test how an REST API handles a POST request that has a body with invalid JSON syntax, for example a missing comma. I'm using node.js to write the API tests. I'm using frisby but I also tried supertest. No luck. With the previous tools, you pass the request body as a JavaScript object, so it's no go. I tried also to pass the invalid JSON as a string without any luck, since a string is also valid JSON (example below). Any ideas?

frisby.create('Ensure response has right status')
    .post('http://example.com/api/books', '{"invalid"}', {json: true})
    .expectStatus(400)
    .toss();
Share Improve this question edited Feb 13, 2015 at 17:11 alefteris asked Feb 2, 2015 at 20:23 alefterisalefteris 1,1268 silver badges21 bronze badges 6
  • Could you provide examples of the string and objects you used ? – Demurgos Commented Feb 2, 2015 at 20:36
  • @Demurgos Added an example, thanks. – alefteris Commented Feb 2, 2015 at 21:16
  • 1 If you need this test, there must be a situation when you expect this error might occur. Can you provide a scenario when this error occurs? – freele Commented Feb 9, 2015 at 17:51
  • Could you post the superagent code you tried? It seems like that library will only do automatic serialization of the data if it's not already a string. – Ben Commented Feb 9, 2015 at 21:52
  • @Ben I meant to type supertest in my question. not the superagent package that the former depends on. But you are right, superagent allows this as I found out, reading its docs. Thanks :) – alefteris Commented Feb 13, 2015 at 17:14
 |  Show 1 more comment

4 Answers 4

Reset to default 7

Using the supertest and mocha packages, you can test an endpoint by posting the invalid JSON like this:

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

The important bit here is type(json). This will set the Content-Type of the request to application/json. With out it, supertest/superagent will default to sending strings as application/x-www-form-urlencoded. Also the invalid JSON is provided as a string and not as a JavaScript object.

I have never used Frisby or superagent, but I find there are two questions here:

1. passing an invalid JSON from client to server using POST method.

Which is not possible because , it will be soon rejected at the client side itself, and you will get error before making a POST request to the server. (because as there are only strings while working with http, the client will itself try to stringify the JSON where it will get stuck with invalid JSON)

2. pass an invalid JSON just as a string

example: POST a string like this using JQuery

 $.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);
    });

This will effectively pass the invalid JSON (name in this case) to the server as a srting. But this will require you to parse the string to JSON using JSON.parse() before you can use it. And when you try that you get this:

SyntaxError: Unexpected token p at Object.parse (native) at Object.app.get.res.send.data [as handle] (/home/ubuntu/workspace/TapToBook.js:35:19) at next_layer (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:103:13) at Route.dispatch (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:107:5) at proto.handle.c (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:195:24) at Function.proto.process_params (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:251:12) at next (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:189:19) at Layer.staticMiddleware [as handle] (/home/ubuntu/workspace/node_modules/express/node_modules/serve-static/index.js:55:61) at trim_prefix (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:226:17) at proto.handle.c (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:198:9)

So whichever packages you use for Rest, you can pass invalid JSON as a string, but not use it.

I assume your test want's to validate the server is handling invalid JSON (and doesn't crash). Hopefully returning a 400 bad request.

Since a POST in http is just a string, an option for the test is to use an API that requires you to supply a JSON object.

If you use raw node http, then you can send whatever invalid string you want:

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

There's also the popular request library.

https://github.com/request/request

For example, with the library, your test could pick up the invalid content from a file and post or put. From their docs:

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

It is actually a simple trick when using npm request library. Here is how I achieved and it is working.

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

Note: Here it is an invalid JSON because ON is without quotes. This will help the testers using request library.

发布评论

评论列表(0)

  1. 暂无评论