Reputation: 419
I have a proxy module, which forwards function calls to services. I want to test if the service function is called, when a function in this proxy module is called.
Here is the proxy module:
const payService = require('../services/pay')
const walletService = require('../services/wallet')
const entity = {
chargeCard: payService.payByCardToken,
// ... some other fn
}
module.exports = entity
Based on this example and this response, I tried to stub the required module 'payService':
const expect = require('expect.js')
const sinon = require('sinon')
const entity = require('../entity')
const payService = require('../../services/pay')
describe('Payment entity,', () => {
it('should proxy functions to each service', () => {
const stub = sinon.stub(payService, 'payByCardToken')
entity.chargeCard()
expect(payService.payByCardToken.called).to.be.ok()
})
})
But the test fails with:
0 passing (19ms)
1 failing
1) Payment entity,
should proxy functions to each service:
Error: expected false to be truthy
at Assertion.assert (node_modules/expect.js/index.js:96:13)
at Assertion.ok (node_modules/expect.js/index.js:115:10)
at Function.ok (node_modules/expect.js/index.js:499:17)
at Context.it (payments/test/entity.js:14:56)
And that's because payService module isn't really stubbed. I know if I add payService as a property of entity and wrap everything with a function, the test will pass:
// entity
const entity = () => {
return {
payService,
chargeCard: payService.payByCardToken,
// .. some other fn
}
}
// test
const stub = sinon.stub(payService, 'payByCardToken')
entity().chargeCard()
expect(payService.payByCardToken.called).to.be.ok()
// test output
Payment entity,
✓ should proxy functions to each service
1 passing (8ms)
But that's code added only for testing puposes. Is there a way to a way to stub module functions without dependency injection and workarounds?
Upvotes: 7
Views: 16225
Reputation: 4907
The problem is that you're stubbing payService
too late, after entity
has already set its mappings.
If you change your test code like so:
const expect = require('expect.js')
const sinon = require('sinon')
const payService = require('../../services/pay')
describe('Payment entity,', () => {
let entity
before(() => {
sinon.stub(payService, 'payByCardToken')
entity = require('../entity')
})
it('should proxy functions to each service', () => {
entity.chargeCard()
expect(payService.payByCardToken.called).to.be.ok()
})
})
...you should find that entity
sets itself up with your stubbed function and the assertion passes okay.
Upvotes: 10