问题
I'm trying to write a standalone test for this simple middleware function
function onlyInternal (req, res, next) {
if (!ReqHelpers.isInternal(req)) {
return res.status(HttpStatus.FORBIDDEN).send()
}
next()
}
// Expose the middleware functions
module.exports = {
onlyInternal
}
This does not work
describe('success', () => {
let req = {
get: () => {return 'x-ciitizen-token'}
}
let res = {
status: () => {
return {
send: () => {}
}
}
}
function next() {}
let spy
before(() => {
spy = sinon.spy(next)
})
after(() => {
sinon.restore()
})
it('should call next', () => {
const result = middleware.onlyInternal(req, res, next)
expect(spy.called).to.be.true <-- SPY.CALLED IS ALWAYS FALSE EVEN IF I LOG IN THE NEXT FUNCTION SO I KNOW IT'S GETTING CALLED
})
})
but this does..
describe('success', () => {
let req = {
get: () => {return 'x-ciitizen-token'}
}
let res = {
status: () => {
return {
send: () => {}
}
}
}
let next = {
next: () => {}
}
let spy
before(() => {
spy = sinon.spy(next, 'next')
})
after(() => {
sinon.restore()
})
it('should call next', () => {
const result = middleware.onlyInternal(req, res, next.next)
expect(spy.called).to.be.true
})
})
Why isn't spying on just the function working?
回答1:
Sinon cannot change content of existing function, so all spies it creates are just wrappers over existing function that count calls, memoize args etc.
So, your first example is equal to this:
function next() {}
let spy = sinon.spy(next);
next(); // assuming that middleware is just calling next
// spy is not used!
Your second example, equals to this:
let next = { next: () => {} }
next.next = sinon.spy(next.next); // sinon.spy(obj, 'name') just replaces obj.name with spy on it
next.next(); // you actually call spy which in in turn calls original next.next
//spy is called. YaY
So, they key to 'spying' and 'stubbing' in sinon is that you have to use spied/stubbed function in test. Your original code just used original, non-spied function.
来源:https://stackoverflow.com/questions/51407877/sinon-spy-on-function-not-working