Sinon 在测试时不会破坏我的实习生功能。 (快递)
Sinon doesn't stub my intern fuctions while testing. (ExpressJS)
目前我想为我的快速路线实施 sinon 存根。问题是,我不明白为什么它没有取代我的功能。
我的测试应该向我的登录路由发出请求,而不是调用身份验证函数,我的登录路由应该调用假函数。知道怎么做吗?
我的项目结构
/src/http/routes/login.js
/src/http/middlewares/user-midd.js
/test/test.js
test.js:
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const chai = require('chai');
const expect = chai.expect;
const chaiHttp = require('chai-http');
chai.use(chaiHttp);
const rawapp = require('../src/http/app');
let stub;
try {
stub = sinon.stub(require('../src/http/middlewares/user-midd').create(),'authenticate')
proxyquire('../src/http/middlewares/user-midd', {
'authenticate': stub
});
stub.callsFake((request, response, next) => {
console.log("IM IN FAKE CALL FUNCTION", request, response, next)
return next()
})
chai.request(rawapp())
.get('/api/v1/de/login')
.set('X-Xamarin-Client-Version', 1)
.then((res) => {
expect(res).to.have.status(200)
done();
}).catch(err => console.error(err))
} catch (err) { console.error(err) }
login.js:
function loginRoute() {
const authenticate = userMiddleware.create().authenticate;
const login = new express.Router({ mergeParams: true });
login.get('/', authenticate, (req, res) => {
logger.info(new Date(), 'In login route GET /');
console.log("LOGIN FUNCTION")
res.status(res.locals.statusCode).json(res.locals.user);
});
return login;
}
module.exports.create = loginRoute;
最后是我的 route-middleware: (user-midd.js)
module.exports.create = function create() {
function authenticate(req, res, next) {
console.log("AUTHENTIFICATION FUNCTION")
const authHeader = req.get('authorization');
const userAuthHeader = req.get('user-authorization') || '';
if (authHeader) {
const mandator = req.params.mandator;
const path = `api/v1/${mandator}/login`;
logger.info(hostname + path);
return request
.get(hostname + path)
.set('Authorization', authHeader)
.set('User-Authorization', userAuthHeader)
.then((mbaasRes) => {
logger.info('Got response from service - status : ', mbaasRes.statusCode);
res.locals.user = {};
res.locals.statusCode = mbaasRes.statusCode;
if (mbaasRes.body) {
res.locals.user = mbaasRes.body;
}
setUserAuthHeader.setHeader(mbaasRes, res);
return next();
})
.catch((err) => {
logger.error('service user call failed - err : ', err);
return next(err);
});
}
const error = {
msg: 'Unauthorized',
statusCode: 401,
};
return next(error);
}
return {
authenticate,
};
};
执行我的测试的结果是:
预期 { Object (_events, _eventsCount, ...) } 的状态码为 200,但得到的是 500'
意味着在测试时,它不会取代 "authenticate" 功能。
我做错了什么?
诗乃可不是这么玩的。如果你想从其他文件中模拟所需的函数,你应该看看 proxyquire.
查看我的 中的一个解释。
这里可能不需要proxyquire,我们可以直接使用Sinon。
这可能有效
...
describe('app test', function() {
beforeEach(function() {
sinon.stub(userMiddleware, 'create').returns({ // use returns of Sinon
authenticate: sinon.stub.callsFake((request, response, next) => {
console.log("IM IN FAKE CALL FUNCTION", request, response, next);
next();
})
});
});
afterEach(function() {
sinon.restore()
});
it('success', function(done) {
chai.request(rawapp())
.get('/api/v1/de/login')
.set('X-Xamarin-Client-Version', 1)
.then((res) => {
expect(res).to.have.status(200)
done();
}).catch(err => console.error(err))
});
})
目前我想为我的快速路线实施 sinon 存根。问题是,我不明白为什么它没有取代我的功能。
我的测试应该向我的登录路由发出请求,而不是调用身份验证函数,我的登录路由应该调用假函数。知道怎么做吗?
我的项目结构
/src/http/routes/login.js
/src/http/middlewares/user-midd.js
/test/test.js
test.js:
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const chai = require('chai');
const expect = chai.expect;
const chaiHttp = require('chai-http');
chai.use(chaiHttp);
const rawapp = require('../src/http/app');
let stub;
try {
stub = sinon.stub(require('../src/http/middlewares/user-midd').create(),'authenticate')
proxyquire('../src/http/middlewares/user-midd', {
'authenticate': stub
});
stub.callsFake((request, response, next) => {
console.log("IM IN FAKE CALL FUNCTION", request, response, next)
return next()
})
chai.request(rawapp())
.get('/api/v1/de/login')
.set('X-Xamarin-Client-Version', 1)
.then((res) => {
expect(res).to.have.status(200)
done();
}).catch(err => console.error(err))
} catch (err) { console.error(err) }
login.js:
function loginRoute() {
const authenticate = userMiddleware.create().authenticate;
const login = new express.Router({ mergeParams: true });
login.get('/', authenticate, (req, res) => {
logger.info(new Date(), 'In login route GET /');
console.log("LOGIN FUNCTION")
res.status(res.locals.statusCode).json(res.locals.user);
});
return login;
}
module.exports.create = loginRoute;
最后是我的 route-middleware: (user-midd.js)
module.exports.create = function create() {
function authenticate(req, res, next) {
console.log("AUTHENTIFICATION FUNCTION")
const authHeader = req.get('authorization');
const userAuthHeader = req.get('user-authorization') || '';
if (authHeader) {
const mandator = req.params.mandator;
const path = `api/v1/${mandator}/login`;
logger.info(hostname + path);
return request
.get(hostname + path)
.set('Authorization', authHeader)
.set('User-Authorization', userAuthHeader)
.then((mbaasRes) => {
logger.info('Got response from service - status : ', mbaasRes.statusCode);
res.locals.user = {};
res.locals.statusCode = mbaasRes.statusCode;
if (mbaasRes.body) {
res.locals.user = mbaasRes.body;
}
setUserAuthHeader.setHeader(mbaasRes, res);
return next();
})
.catch((err) => {
logger.error('service user call failed - err : ', err);
return next(err);
});
}
const error = {
msg: 'Unauthorized',
statusCode: 401,
};
return next(error);
}
return {
authenticate,
};
};
执行我的测试的结果是: 预期 { Object (_events, _eventsCount, ...) } 的状态码为 200,但得到的是 500'
意味着在测试时,它不会取代 "authenticate" 功能。 我做错了什么?
诗乃可不是这么玩的。如果你想从其他文件中模拟所需的函数,你应该看看 proxyquire.
查看我的
proxyquire,我们可以直接使用Sinon。
这可能有效
...
describe('app test', function() {
beforeEach(function() {
sinon.stub(userMiddleware, 'create').returns({ // use returns of Sinon
authenticate: sinon.stub.callsFake((request, response, next) => {
console.log("IM IN FAKE CALL FUNCTION", request, response, next);
next();
})
});
});
afterEach(function() {
sinon.restore()
});
it('success', function(done) {
chai.request(rawapp())
.get('/api/v1/de/login')
.set('X-Xamarin-Client-Version', 1)
.then((res) => {
expect(res).to.have.status(200)
done();
}).catch(err => console.error(err))
});
})