这是我的第一个快速应用程序,我在为端点编写测试时遇到了一些麻烦。
目前我没有使用数据库来存储令牌或在登录时检查用户。
我写的测试通过了,但是它们并不完整。我如何测试例如正确验证的用户?
我如何模仿身份验证过程?
因为我已经创建了一个全局中间件函数和checkLoging
函数如何将这些函数纳入我的测试中?
如何测试身份验证和路由?
这是我的代码:
'use strict';
var express = require('express');
var session = require('express-session');
var app = express();
var shopifyObj = require('shopify-node');
var shopifyConfig = require("./config/config.json");
var _ = require('underscore');
var shopify = require('./lib/modules/shopify');
var product = require('./lib/modules/product');
var fakeDta = {
user: 'Simba',
};
app.use(session({
secret: 'dsjkfhklaf',
resave: false,
saveUninitialized: true
}));
// Set global middleware function to check for sessions
app.use(function(req, res, next) {
if (req.session && req.session.user) {
// check here for the existence of this user and token in the database.
next();
} else {
next();
}
});
// define middleware function
function checkLogin (req, res, next) {
if (!req.session.user) {
req.session.error = 'Access denied!';
res.redirect('/auth');
} else {
next();
}
};
app.get('/auth', function (req, res) {
var url = shopify.createURL();
res.redirect(url);
});
app.get('/handle-o-auth-response', function (req, res) {
var code = req.query.code;
_.extend(shopifyConfig, {'code': code});
shopify.setAccessCode(code, res, function (err, token) {
if (err) {
res.redirect('/auth');
} else {
_.extend(shopifyConfig, {'access_token': token});
req.session.user = fakeDta.user;
res.redirect('/products');
}
});
});
app.get('/products', checkLogin, function (req, res) {
shopify = new shopifyObj(shopifyConfig);
product.getProducts(shopify, res);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('App listening at http://%s:%s', host, port);
});
module.exports = server;
这些是我的测试:
"use strict";
var supertest = require("supertest");
describe("Testing server",function(){
var server;
beforeEach(function () {
/* Node module system caches the evaluated result of each module
to avoid loading and compiling the same javascript file multiple times.
Thus the server instance from app.js is only created once.
*/
delete require.cache[require.resolve('../app.js')];
server = require('../app.js');
});
afterEach(function (done) {
server.close(done);
});
it("should redirect to /auth",function(done){
supertest(server)
.get("/products")
//.expect("Content-type",/json/)
.expect(302, done);
});
it("should redirect to shopify",function(done) {
supertest(server)
.get("/auth")
//.expect("Content-type",/json/)
.expect(302, done);
});
});
答案 0 :(得分:1)
我要做的是重构代码以支持模拟或替换checkLogin函数。
你可以通过从app.js公开导出对象的checkLogin函数来做到这一点,但这在架构上不会很干净。
或者,您可以将checkLogin函数分离到它自己的文件,而不是导出:
module.exports = server;
创建一个函数,该函数接受包含使用checkLogin函数的所有代码的checkLogin函数:
var express = require('express');
// skipped require code...
var product = require('./lib/modules/product');
function init(checkLogin) {
var fakeDta = {
user: 'Simba',
};
// skipped code...
// remove the checkLogin function definition!
// skipped code...
return app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('App listening at http://%s:%s', host, port);
});
};
module.exports = init;
现在在您的实时代码中,您需要带有checkLogin函数的文件,并将该函数传递给服务器,并且在您的测试代码中,您可以提供一个模拟函数,该函数将在您的测试中完全按照您的需要运行,例如返回登录有效。
您可以编写自己的函数并传递该函数,也可以使用像sinon这样的模拟库。
答案 1 :(得分:0)
我有env的json配置文件:test,dev,prod和config loader,根据当前的NODE_ENV返回config:
let ENV = process.env.NODE_ENV;
let env = ENV || 'prod';
module.exports = require('./' + env + '.json');
在授权中间件中:
if(config.env != 'prod' && process.env.DISABLE_AUTORIZATION) return next();
现在我可以通过设置DISABLE_AUTHORIZATION变量来禁用test和dev环境中的中间件:
process.env.DISABLE_AUTORIZATION = true;
PS。要设置NODE_ENV,我使用package cross-env。我的脚本:
"scripts": {
"start": "node server.js",
"dev": "cross-env NODE_ENV=dev node server.js",
"test": "mocha --timeout 10000"
},