Test how API handles invalid JSON syntax request body using node.js
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.
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 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'))