Supertest: Supertest fails on Content-Type

Created on 6 Dec 2014  Â·  19Comments  Â·  Source: visionmedia/supertest

Supertest says the content-type is text/plain, but when I use Postman or Chrome devtools and check the network tab, it correctly shows the content-type as text/html.

describe('Core controller unit tests:', function() {
    before(function(done) {
        request = request('http://localhost:3001');

        done();
    });

    describe('Loading the homepage', function() {
        it('should return 200 from GET /', function(done) {
            request
                .get('/')
                .expect('Content-Type', /html/)
                .expect(200, done);
        });
    });

    after(function(done) {
        done();
    });
});
question

Most helpful comment

+1 always getting "text/html; charset=utf-8" no matter what I do.

    it('should respond with a 200 if the posted body is valid', function(done) {
        request(app)
            .post('/user/', {
                json: true,
                body: helpers.getUser()
            })
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(function(response) {
                debugger;
                response.res.json.id.should.eql('123');
            })
            .expect(200)
            .end(done);
    });

app.post('/user/', validate({body: helpers.getUserSchema()}), function(req, res) {
   res.set('Content-Type', 'applicaton/json'); 
   res.json({
        id: '1234'
    });
});

All 19 comments

Bump.

@gjohnson any thoughts on what's going on?

@gjohnson this still doesn't work for me..I'm positive my content-type is correct, can you take a look at this?

@gjohnson when using an API tester like the Postman Chrome app, I get the content-type as text/html, so what is going on exactly?

+1 always getting "text/html; charset=utf-8" no matter what I do.

    it('should respond with a 200 if the posted body is valid', function(done) {
        request(app)
            .post('/user/', {
                json: true,
                body: helpers.getUser()
            })
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(function(response) {
                debugger;
                response.res.json.id.should.eql('123');
            })
            .expect(200)
            .end(done);
    });

app.post('/user/', validate({body: helpers.getUserSchema()}), function(req, res) {
   res.set('Content-Type', 'applicaton/json'); 
   res.json({
        id: '1234'
    });
});

same here

@gjohnson any status on this?

@ilanbiala not sure it will help, maybe you should try setting the accept header of your supertest request.

    request(app)
            .get('/')
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200, done);

@ilanbiala can you attach the sample Postman request and response (with headers) that is working for your example? Is there some server redirect that is happening with the requests as that could change the response types.
We use expect Content-Type in almost all our tests and it works for json, html, etc.

Hi all, I don't think there is anything wrong with supertest, or superagent.
Here is a quick test file I wrote that shows things working as they should for a basic express set up.

var request = require('supertest')
  , express = require('express');

var app = express();

app.post('/user/json', function(req, res) {
   res.set('Content-Type', 'application/json');
   res.json({
        id: '1234'
    });
});

app.post('/user/html', function(req, res) {
   res.set('Content-Type', 'text/html');
   res.send('id: 1234');
});


describe('POST /user/json', function(){
    it('should respond with a json 200 response setting Accept header', function(done) {
        request(app)
            .post('/user/json', {
                json: true,
                body: '{"id":"100","name":"Mike"}'
            })
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200)
            .end(done);
    });
    it('should respond with a json 200 not setting Accept header', function(done) {
        request(app)
            .post('/user/json', {
                json: true,
                body: '{"id":"100","name":"Mike"}'
            })
            .expect('Content-Type', /json/)
            .expect(200)
            .end(done);
    });
});

describe('POST /user/html', function(){
    it('should respond with an html 200 response setting Accept header', function(done) {
        request(app)
            .post('/user/html', {
                json: true,
                body: '{"id":"100","name":"Mike"}'
            })
            .set('Accept', 'application/json')
            .expect('Content-Type', /html/)
            .expect(200)
            .end(done);
    });
    it('should respond with an html 200 not setting Accept header', function(done) {
        request(app)
            .post('/user/html', {
                json: true,
                body: '{"id":"100","name":"Mike"}'
            })
            .expect('Content-Type', /html/)
            .expect(200)
            .end(done);
    });
});

Does supertest match Content-Type: application/json; charset=/whichevercharset/ with .expect('Content-Type', /json/) ?

What should I write to make it do it ?

@danielmihai yes if you pass a regex as the second argument to .expect it will match in your example.

ie:
.expect('Content-Type', /json/) will match application/json; charset=utf-8

Just FYI for other dummies like me whose tests failed on .expect("Content-Type", /json/)

My mistake was refactoring this bit of code from

res.status(statusCode).send(err); // err is an object

to

res.status(statusCode).send(message); // string from the err object

When the correct way would be

res.status(statusCode).send({ message, });

By default if the data is not inside curly brackets it will be rendered as html, not json. And the reason why I couldn't see it with Postman was because it still sends err-objects while in development environment, not test. Every day I relearn something new...

`request(app)
          .get('/')
          .expect('Content-Type','text/html; charset=utf-8')
          .end(done);

    });
`

will work perfectly whereas

`request(app)
          .get('/')
          .expect('Content-Type','text/html')
          .end(done);

    });` 

won't work because the http header received adds an encoding of utf-8

You could use a regexp to match your expected content type. /text\/html/
would pass your test.

On Tue, Mar 28, 2017 at 2:18 PM, Simo notifications@github.com wrote:

`request(app)
.get('/')
.expect('Content-Type','text/html; charset=utf-8')
.end(done);

});

while work perfectly whereasrequest(app)
.get('/')
.expect('Content-Type','text/html')
.end(done);

});`

won't work because the http header received adds an encoding of utf-8

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/visionmedia/supertest/issues/187#issuecomment-289738784,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABzKA4SGG70kSVqw3EBhJRtGNTpkvr37ks5rqOyVgaJpZM4DFFa6
.

it is work to return as a json~

describe('Loading the homepage', function() {  
      it('should return 200 from GET /', function(done) {  
            request  
            .get('/')  
            .set('Content-Type', 'application/json')  
            .expect(200, done);  
       });  
});

Had this error in an older project using https://www.npmjs.com/package/express-force-https ... not a very popular package, but it will cause Express to always return 302 with html/text when using Supertest. With the tests expecting Content-Type of /json/ of course. Easy fix was to not use this package in test env. Commenting here in the off chance it saves someone else several hours of googling and debugging.

As the issue is closed I suppose that I'm doing something wrong here and some help would be appreciated.

const express = require('express');

var app = express();

app.get('/', (req, res) => {
    res.status(404).send({
        error: 'Page not found.',
        name: 'Todo App v1.0'
    });
});

app.listen(3000);
module.exports.app = app;
const request = require('supertest');
const expect = require

var app = require('./server').app;

describe('Server', () => {
    describe('GET /', () => {
        it('Should return hello world response', (done) => {
            request(app)
                .get('/')
                .expect(404)
                .expect((res) => {
                    expect(res.body).toInclude({
                        error: "Page not found."
                    });
                })
                .end(done);
        });
    });
});

My error message is the same

  1) Server
       GET /
         Should return hello world response:
     TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received type object
      at validateString (internal/validators.js:125:11)
      at Module.require (internal/modules/cjs/loader.js:652:3)
      at require (internal/modules/cjs/helpers.js:22:18)
      at request.get.expect.expect (server/server.test.js:13:21)
      at Test._assertFunction (node_modules/supertest/lib/test.js:283:11)
      at Test.assert (node_modules/supertest/lib/test.js:173:18)
      at Server.localAssert (node_modules/supertest/lib/test.js:131:12)
      at emitCloseNT (net.js:1599:8)
      at process.internalTickCallback (internal/process/next_tick.js:72:19)

@LeoLiu1209 Thank you. Your solution works perfectly for me. I've to comment out .expect('Content-Type', /json/) and the test run smoothly but when I deleted the line that I 've commented out the test failed. Why is that? I'm a newbie.

Was this page helpful?
0 / 5 - 0 ratings