2017-06-29 45 views
0

我有一个模块要使用Tape和Sinon进行测试。不幸的是我做得不好。这里是模块代码:无法用磁带/ Sinon单元测试JavaScript函数

let config = require('./config'); 
let request = require('request'); 
let restify = require('restify'); 

let certificateUtils = require('utilities'); 

const validateTheToken = function (token, requestId, callback) { 

    const options = { 
    url: config.userServiceRootUrl + config.validationPath, 
    method: 'POST', 
    headers: { 
     'token': token, 
     'caller': config.callingService, 
     'x-request-id': requestId 
    } 
    }; 

    if (typeof process.env.CA_STORE !== 'undefined') { 
    const certAuth = process.env.CA_STORE + '/trustedCA.pem'; 
    options.ca = certificateUtils.getAuthorisedCerts(certAuth); 
    } 

    request(options, function (error, response, body) { 
    callback(error, response, body); 
    }); 
}; 

// add token validation middleware 
const authenticateTheToken = function (req, res, next) { 
    if (config.enableTokenValidation) { 

    const receivedToken = getToken(req); 
    if (!receivedToken) { 
     return next(new restify.NotAuthorizedError('No token')); 
    } 

    validateTheToken(receivedToken, req.requestId, function (err, response, body) { 
     if (err || response.statusCode != 200) { 
     req.logger.error({ 
      err: err, 
      response: response ? { 
      statusCode: response.statusCode, 
      statusMessage: response.statusMessage, 
      body: body 
      } : undefined, 
     }, 'validation failed'); 
     return next(new restify.NotAuthorizedError('Not a valid token')); 
     } else { 
     return next(); 
     } 
    }); 
    } 
    else { 
    return next(); 
    } 
}; 

function getTheToken(req) { 


    if (req.headers.token) { 
    return req.headers.token; 
    } else if (req.headers.user) { 
    req.logger.warn({req, user: req.headers.user}, `request was sent with header 'user'`); 
    try { 
     return JSON.parse(req.headers.user).token; 
    } catch (e) { 
     req.logger.warn({user: req.headers.user}, `is not valid JSON`); 
     return null; 
    } 
    } else { 
    return null; 
    } 
} 

module.exports = {getTheToken, authenticateTheToken}; 

我怎么能首先对authenticateTheToken进行单元测试?这里是我的尝试: 测试( '访问authenticateTheToken',函数(T){

const tokenAuthentication = require('../tokenAuthentication'); 
const authenticateToken = tokenAuth.authenticateToken; 

let req = { 
    headers: { 
     token: 1 
    } 
}; 
let res = {}; 
let next = {}; 

let stub = sinon.stub(tokenAuth, 'getToken'); 

stub.yields('next'); 

authenticateToken(req, res, next); 

t.equal(authenticateToken.callCount, 1); 
t.end(); 
}); 

当我运行测试我凸轮收到以下错误:

C:\source\my-project\tokenAuthentication.js:40 
    req.logger.error({ 
      ^

TypeError: Cannot read property 'error' of undefined 
    at C:\source\my-project\tokenAuthentication.js:40:19 
    at Request._callback (C:\source\my-project\tokenAuthentication.js:25:5) 
    at self.callback (C:\source\my-project\node_modules\request\request.js:188:22) 
    at emitOne (events.js:96:13) 
    at Request.emit (events.js:188:7) 
    at Request.init (C:\source\my-project\node_modules\request\request.js:234:17) 
    at new Request (C:\source\my-project\node_modules\request\request.js:130:8) 
    at request (C:\source\my-project\node_modules\request\index.js:54:10) 
    at validateTheToken (C:\source\my-project\tokenAuthentication.js:24:3) 
    at authenticateTheToken (C:\source\tokenAuthentication.js:38:5) 


npm ERR! Test failed. See above for more details. 

回答

0

您在这里嘲讽req,所以req在您的测试需要有所有的req在你的代码的属性。这包括记录器。

req = { 
    ... 
    logger: { 
    warn:() => {}, 
    error:() => {}, 
    } 
} 

req可能有很多属性,因此您可能要创建一个真正的Request对象或使用另一个库来嘲讽http请求,如nock