admin管理员组

文章数量:1180547

I'm testing an express server using super-test and I need to test a post call. I assume the post should be successful and return a status of 200 but it is returning 401. I've been told by someone that I need to pass a request body with the post but I'm unsure exactly how to do this.

I've attempted to use .send({name: 'aName'}) but that gives me the same 401 code.

Below is the app.js

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const hateoasLinker = require('express-hateoas-links');
const AValidator = require('./AValidator');
const BValidator = require('./BValidator');
const schema_v1 = require("./schema.json");
const {
    logService: logger
} = require("@utils");

let aValidator = AValidator(schema_v1);

let ValidatorApi = BValidator.ValidatorApi('api');
let adminValidator = BValidator.ValidatorAdmin('admin');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(hateoasLinker);

app.post('/*/activate',admiValidator, (req, res) => {
    console.log("In Activate===============>");
    res.status(200);
    res.json({
        rel: "self",
        method: "POST",
        title: 'Activate Solution',
        href: "/activate"
    });
});

Here is the code for the BValidator

ValidatorAdmin = function(callType){
    return function (req,res,next){
        let authoizationHeader = req.headers['authorization'];
        try {
        Verifier.verifyPayload(authoizationHeader, callType, (verificationError) => {
            if (verificationError) {
                res.setHeader('Content-Type', 'application/json');
                res.status(401);
                res.json({
                    message : "verificationError "+verificationError.message
                });
            } else {
                next();
            }
        });
        } catch (authorizationError) {
            res.setHeader('Content-Type', 'application/json');
            res.status(401);
            res.json({
                message : authorizationError.message
            });

        }
    }
}

Here is the app.test.js

const request = require('supertest');
const bodyParser = require('body-parser');
let AValidator = require('../src/AValidator');
let BValidator = require('../src/BValidator');
BValidator = jest.fn();
AValidator = jest.fn();
app = require('../src/app');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

describe('Test os GET/POST calls in app.js', ()=>{

  test('Tests activate post', (done)=>{

    BValidator.mockReturnValue({
      ValidatorApi: (req,res,next)=>{
        next();
      },
      ValidatorAdmin:(req,res,next)=>{
        next();
      }
    });

    AValidator.mockImplementation((schema)=>{
      return function (req,res,next){
        next();
      }
    });


    request(app)
      .post('/test/activate')
      .set({name:'josh'})
      .then((response)=>{
        expect(response.statusCode).toBe(200);
        done();
      })

  })


});

So ultimately I'd like this post to resolve successfully and return a status code of 200.

I'm testing an express server using super-test and I need to test a post call. I assume the post should be successful and return a status of 200 but it is returning 401. I've been told by someone that I need to pass a request body with the post but I'm unsure exactly how to do this.

I've attempted to use .send({name: 'aName'}) but that gives me the same 401 code.

Below is the app.js

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const hateoasLinker = require('express-hateoas-links');
const AValidator = require('./AValidator');
const BValidator = require('./BValidator');
const schema_v1 = require("./schema.json");
const {
    logService: logger
} = require("@utils");

let aValidator = AValidator(schema_v1);

let ValidatorApi = BValidator.ValidatorApi('api');
let adminValidator = BValidator.ValidatorAdmin('admin');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(hateoasLinker);

app.post('/*/activate',admiValidator, (req, res) => {
    console.log("In Activate===============>");
    res.status(200);
    res.json({
        rel: "self",
        method: "POST",
        title: 'Activate Solution',
        href: "/activate"
    });
});

Here is the code for the BValidator

ValidatorAdmin = function(callType){
    return function (req,res,next){
        let authoizationHeader = req.headers['authorization'];
        try {
        Verifier.verifyPayload(authoizationHeader, callType, (verificationError) => {
            if (verificationError) {
                res.setHeader('Content-Type', 'application/json');
                res.status(401);
                res.json({
                    message : "verificationError "+verificationError.message
                });
            } else {
                next();
            }
        });
        } catch (authorizationError) {
            res.setHeader('Content-Type', 'application/json');
            res.status(401);
            res.json({
                message : authorizationError.message
            });

        }
    }
}

Here is the app.test.js

const request = require('supertest');
const bodyParser = require('body-parser');
let AValidator = require('../src/AValidator');
let BValidator = require('../src/BValidator');
BValidator = jest.fn();
AValidator = jest.fn();
app = require('../src/app');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

describe('Test os GET/POST calls in app.js', ()=>{

  test('Tests activate post', (done)=>{

    BValidator.mockReturnValue({
      ValidatorApi: (req,res,next)=>{
        next();
      },
      ValidatorAdmin:(req,res,next)=>{
        next();
      }
    });

    AValidator.mockImplementation((schema)=>{
      return function (req,res,next){
        next();
      }
    });


    request(app)
      .post('/test/activate')
      .set({name:'josh'})
      .then((response)=>{
        expect(response.statusCode).toBe(200);
        done();
      })

  })


});

So ultimately I'd like this post to resolve successfully and return a status code of 200.
Share Improve this question edited Mar 31, 2019 at 15:14 Nino Filiu 18.5k11 gold badges62 silver badges96 bronze badges asked Mar 29, 2019 at 19:40 jwolsbornjwolsborn 7162 gold badges8 silver badges29 bronze badges 24
  • You probably need .post('/test/activate', {name: 'josh'}).. and remove the .set – Isaac Vidrine Commented Mar 29, 2019 at 19:47
  • unfortunately that doesn't work either :-( – jwolsborn Commented Mar 29, 2019 at 19:48
  • Okay, just looked at supertest docs. If .send didn't work, then theres a problem with the admiValidator. Im assuming it expects a token or something in the header of the request, and if there isn't returns 401 unauthorized. – Isaac Vidrine Commented Mar 29, 2019 at 19:50
  • Well I did just notice that when i use .send I get a 400 error instead of a 401. So I guess that's a change at least – jwolsborn Commented Mar 29, 2019 at 19:52
  • Have you tried testing out the endpoint manually in postman? – Isaac Vidrine Commented Mar 29, 2019 at 19:53
 |  Show 19 more comments

2 Answers 2

Reset to default 35

I am assuming you have set the parser correctly. Example:

 const app = express();
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({extended: true}));

Once this is set, I believe you're missing the headers. Example:

const payload = {name: 'john', email: '[email protected]', password: '2342388' };
const res = await request(app)
            .post('/api/register')
            .send(payload)
            .set('Content-Type', 'application/json')
            .set('Accept', 'application/json')

Your problem is that you have a wrong understanding of what those mock functions are doing. First of all, you are completely overwriting the original values of AValidator and BValidator with jest.fn().

So doing

let AValidator = require('../src/AValidator');
let BValidator = require('../src/BValidator');

in your test is redundant.

The purpose of mockReturnValue is so that you can call that function and get back the return value you specified.

Taken straight from Jest docs

const myMockFn = jest
  .fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call');

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());

You are never using or calling your mock functions, and furthermore your api has no clue they even exist.

The solution is to provide the appropriate headers in the request when you run your tests so they don't fail in the middleware. Also, to do that, you have to know what Verifier.verifyPayload is doing.

with supertest your request should look like

request(app)
.post('/test/activate')
.set({authorization: 'a_valid_value_goes_here'})
.then((response)=>{
   expect(response.statusCode).toBe(200);
   done();
})

本文标签: javascriptPassing request body to post using supertestStack Overflow