@tapjs/sinon
A tap plugin for using sinon
A t.sinon
property is added to tests, which is a Sinon
sandbox for that
single test. When the test is completed, the sandbox is torn
down automatically, but you can also of course call
t.sinon.restore()
to remove all fakes and spies and such.
Also adds a sinon
property to the test config, which can be
used to configure the sinon property. If no config is specified,
then it uses sinon.defaultConfig
, which enables everything.
Install @tapjs/sinon
, and add '@tapjs/sinon'
to your plugin
config list in package.json
or .taprc
.
# install the plugin:
npx tap plugin add @tapjs/sinon
# or, manually:
npm install --save-dev @tapjs/sinon
# add '@tapjs/sinon' to plugins list
vim .taprc
# rebuild tap with the plugin applied
npx tap plugin build
If you're using this, you may want to disable the built-in
@tapjs/intercept
plugin, because it has a very similar use
case, but is much more limited in scope than sinon.
tap plugin rm @tapjs/intercept
Just use the t.sinon
property, it's a sinon sandbox and it
automatically cleans itself up when the test is done.
import t from 'tap'
const myAPI = { hello: () => {} }
t.test('some child test', t => {
// this stub call is only relevant within this test
t.sinon.stub(myAPI, 'hello')
myAPI.hello()
t.sinon.assert.calledOnce(myAPI.hello)
t.end()
})
t.test('another test', async t => {
// myAPI.hello is no longer a sinon stub
})
t.test(
'sinon with a config object',
{
sinon: {
injectInto: null,
useFakeTimers: true,
},
},
async t => {
// t.sinon only has the configured setup here
},
)
Sinon does not behave properly if fake timers are assigned to the
same global object more than once, resulting in a 'Can't install fake timers twice on the same global object.'
error.
By default, this library sets { useFakeTimers: false }
in the
options to avoid this. You can enable fake timers in a given test
by setting it in the sinon
option as shown in the examples
above, but note that it can only be used in a single place in a
test heirarchy.
For example:
// ok, works fine
t.test(
'fake timers test one',
{ sinon: { useFakeTimers: true } },
t => {
t.test('child test', t => {
// etc.
})
},
)
t.test(
'second fake timers test',
{ sinon: { useFakeTimers: true } },
t => {
// etc.
},
)
// this, however, does not work:
t.test('parent', { sinon: { useFakeTimers: true } }, t => {
t.test('child', { sinon: { useFakeTimers: true } }, t => {
// will throw an error
})
})