Home > Back-end >  How to get response body from Express.js server using Supertest?
How to get response body from Express.js server using Supertest?

Time:02-10

I started to write some tests for my application and I have issues to read/get response from the server. I tried many things but nothing really worked, can someone help me please ?

// /api/checkCreds
exports.checkCreds = async function(req, res){
//validation
if(!await User.checkCreds(req.body.username, req.body.password)){
    var result = {error: true, data: "Incorrect"}
    res.sendStatus = 401;
    return res.send(JSON.stringify(result));        
}

If credentials sent to the server aren't matching, return a response with "Incorrect" message back to the user. In the test I'm trying to get data from the server to check if properties are matching the expected output.

    //test.js
    it("We should fail with HTTP code 401 because incorrect data is passed (username='incorrect' password='incorrect')", function(done){
       supertest(app)
       .post('/api/checkCreds')
       .send({username: 'incorrect', password: 'incorrect'})
       .expect({error: true, data: "Incorrect"})
       .expect(401, done);
   });

When ran, test fails because expected properties are different from the response sent by the server, which is an empty object {}.

Error given by the console

Any help is appreciated.

CodePudding user response:

You may try changing your first expect to see if you can coax supertest into showing you the actual body that it's comparing to. For example, expect('')

If that doesn't work, there's a version of expect that accepts a function. In that function, you should be able to print out what you are getting in the response body, ie. console.log(res).

It may be that there's some confusion with the JSON return type-- I haven't used that directly. You could try expecting JSON.

Finally, there's a strange paragraph in the documentation that I don't think applies, but I thought I'd mention:

One thing to note with the above statement is that superagent now sends any HTTP error (anything other than a 2XX response code) to the callback as the first argument if you do not add a status code expect (i.e. .expect(302)).

CodePudding user response:

While trying to fix my issue, I noticed that in the HTTP response, Content-Type header was set to text/plain and my server was returning JSON, so that probably was the thing that confused supertest.

I think that res.send() sets the header to text/plain by default and I had to manually set the header value to application/json by using res.type('json'). At that point I was able to read the response body without an issue. I also learned that res.json() sets the Content-Type header to application/json by default, so you don't need to do it manually like with res.send().

Working code:

// /api/checkCreds
if(!await User.checkCreds(req.body.username, req.body.password)){
    var result = {error: true, data: "Incorrect"}
    return res.status(401).json(result);       
}

//test.js
it("We should fail with HTTP code 401 because incorrect data is passed (username='incorrect' password='incorrect')", function(done){
    supertest(app)
    .post('/api/checkCreds')
    .set('Content-type', 'application/json')
    .send({username: 'incorrect', password: 'incorrect'})
    .expect(401)
    .expect(function(res){
        console.log(res.body);
    })
    .end(done); 
});

Feel free to correct me if I stated something that isn't quite right.

  • Related