【问题标题】:NodeJs: next is not functionNodeJs:下一个不是功能
【发布时间】:2017-07-02 17:07:23
【问题描述】:

我尝试使用 Mocha、Chai 和 Supertest 编写单元测试,但不幸的是,现在没有成功。
我有下一条路线:

var express = require('express');
var GoogleUrl = require('google-url');
var _ = require('lodash');
var token = require('../middlewares/token');
var Url = require('../models/url');
var config = require('../config');
var router = express();

router.post('/urls/create', token.required, createShortUrl);

module.exports = router;

function createShortUrl(req, res) {

    _.trim(req.body.list_tags);
    var tags = _.split(req.body.list_tags, ',');
    tags.splice(tags.length - 1, 1);

    var date = returnDate();
    var time = returnTime();

    var googleUrl = new GoogleUrl({
        'key': config.get('google_key')
    });

    googleUrl.shorten(req.body.full_url, function (err, shortUrl) {

        if (err) {
            res.status(500).json(err);
        }

        var url = new Url({
            'author': req.payload.username,
            'description': req.body.description,
            'full_url': req.body.full_url,
            'short_url': shortUrl,
            'list_tags': tags,
            'date': date,
            'time': time
        });

        url.save(function (err) {

            if (err) {
                res.status(500).json(err);
            } else {
                res.status(200).json('Shortener url is created!');
            }

        });

    });

}

   function returnDate() {
    var d = new Date();
    var yyyy = d.getFullYear();
    var mm = d.getMonth() < 9 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1);
    var dd = d.getDate() < 10 ? '0' + d.getDate() : d.getDate();
    return dd + '-' + mm + '-' + yyyy;
}

function returnTime() {
    var d = new Date();
    var hh = d.getHours() < 10 ? '0' + d.getHours() : d.getHours();
    var min = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes();
    var ss = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds();
    return hh + ':' + min + ':' + ss;
}

我使用 Mongoose 将数据保存在 MongoDB 中。 对于路线,我编写了单元测试:

var app = require('../server');
var chai = require('chai');
var request = require('supertest');
var jwt = require('express-jwt');
var config = require('../config');

var expect = chai.expect;

describe('Urls Tests', function () {

  var url = {
    author : 'Alexey',
    description : 'grrggr',
    full_url : 'https://github.com',
    short_url : 'short_url_by_google',
    date : '30-06-2017',
    time : '18:21:27',
    count_click : 0,
    list_tags : [
      'Sport',
      'Football'
    ]
  };

  var token = {
    required: jwt({
      secret: config.get('jwtSecret'),
      userProperty: 'payload',
      getToken: 'token',
    })
  };

describe('## Create url ', function() {
    it('should create a url', token.required, function(done) {
      request(app)
        .post('/urls/create')
        .send(url)
        .end(function(err, res) {
        expect(res.statusCode).to.equal(200);
        expect(res.body.author).to.equal('Alexey');
        url = res.body;
        done();
      });
    });
  });

});

当我运行单元测试时出现错误:

TypeError: next is not a function
      at Context.middleware (node_modules\express-jwt\lib\index.js:76:16)

我不明白为什么我得到它。请帮帮我 ! 我认为我创造了很少的错误,因为可以找到。

更新

middlewares/token.js

var jwt = require('express-jwt');
var config = require('../config');

function getTokenFromHeader(req){
    if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Token') {
        return req.headers.authorization.split(' ')[1];
    }

    return null;
}

var token = {
    required: jwt({
        secret: config.get('jwtSecret'),
        userProperty: 'payload',
        getToken: getTokenFromHeader
    })
};

module.exports = token;

【问题讨论】:

  • 我发布了我的middleware/token 文件。

标签: node.js unit-testing mocha.js chai supertest


【解决方案1】:

错误在您的it('should create a url', token.required, function(done) 行。因为令牌应该是一个中间件,所以它需要参数reqresnext

在您的测试中,您没有向服务器提供令牌,因此您可以从测试中删除 token.required。

但是,如果您确实对令牌身份验证进行了测试,则可以通过在测试中使用自己的 next 函数手动调用 token.required 来解决此问题。您还需要在请求中为服务器提供 jwt。

【讨论】:

    【解决方案2】:

    it('should create a url', token.required, function(done) {

    Mocha 测试不允许使用Connect 样式的中间件。如果没有这种支持,将token.required 传递给it() 将调用token.requiredjwt()token.required 中尝试调用回调 next,它是 Connect 中间件函数 args 的一部分

    const express = require('express')
    const server = express()
    
    server.use((req, res, next) => {
      console.log('this is middleware')
      return next() // Call next middleware 
    })
    

    考虑到您想测试路线,您无论如何都不需要这样做。如果路线正常工作,它将需要密钥并且可以工作。您可以通过在没有 JWT 的情况下发出请求并通过状态代码断言它失败来测试该场景。

    【讨论】:

      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 2021-11-12
      • 2020-01-03
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      相关资源
      最近更新 更多