Stub not working with sinon.match
crimx opened this issue · comments
I'm having trouble making sinon-chrome stubs work with sinon.match
.
I use webpack, karma, mocha and sinon-chai. The spec below may reproduce the error.
It looks like sinon-chrome's stub doesn't recognize sinon.match
and treats it like a normal object. The error is "AssertionError: expected stub to have been called with arguments hasOwn("key")%D", while it should be "arguments matching hasOwn("key")%D".
Any idea what went wrong?
describe('Sinon Native Stub', function () {
it('calledWithMatch + match', function () {
const stub = sinon.stub()
stub({key: 'value'})
stub.should.be.calledWithMatch(sinon.match.hasOwn('key'))
})
it('calledWith + match', function () {
const stub = sinon.stub()
stub({key: 'value'})
stub.should.be.calledWith(sinon.match.hasOwn('key'))
})
it('withArgs + match', function () {
const stub = sinon.stub()
stub({key: 'value'})
stub.withArgs(sinon.match.hasOwn('key')).should.be.calledOnce
})
})
describe('Sinon Chrome Stub', function () {
it('calledWithMatch + match', function () {
chrome.storage.local.set({key: 'value'})
chrome.storage.local.set.should.be.calledWithMatch(sinon.match.hasOwn('key'))
})
it('calledWith + match', function () {
chrome.storage.local.set({key: 'value'})
chrome.storage.local.set.should.be.calledWith(sinon.match.hasOwn('key'))
})
it('withArgs + match', function () {
chrome.storage.sync.set({key: 'value'})
chrome.storage.sync.set.withArgs(sinon.match.hasOwn('key')).should.be.calledOnce
})
})
Results:
Sinon Native Stub
√calledWithMatch + match
√calledWith + match
√withArgs + match
Sinon Chrome Stub
√calledWithMatch + match
×calledWith + match
AssertionError: expected stub to have been called with arguments hasOwn("key")%D
×withArgs + match
AssertionError: expected stub to have been called exactly once, but it was called 0 times
Is this problem related to #66 ?
No I think it was related to Sinon. I was using vue-cli which generates Sinon v4.x dependency. I think it might not be compatible with Sinon Chrome.
Anyway I ended up using jest with sinon-chrome and let jest handle the matching,
I've encountered the same issue, it seems that it's not possible to use sinon.match
if sinon
isn't the very instance sinon-chrome
is using internally.
Here's how one can reproduce:
- Create folder
test
- Create folder
1
and folder2
insidetest
- Inside
test/1
:npm install sinon
- Inside
test/2
:npm install sinon-chrome
- Inside
test/2
createtest.js
with the following content and execute withnode test.js
const sinon = require('sinon');
const browser = require('sinon-chrome/webextensions');
browser.tabs.create({foo: 'bar'});
console.log(browser.tabs.create.calledWith({
foo: sinon.match.string
}));
const otherSinon = require('../1/node_modules/sinon');
console.log(browser.tabs.create.calledWith({
foo: otherSinon.match.string
}));
Actual result
true
false
Expected result
true
true
Note
This is a rather fabricated example, but I've seen it happen inside just one module since I believe it's still possible that different version reside in the same node_modules folder
A workaround is to pass in your own sinon or use the exposed sinon from sinon-chrome
, I'll provide a Pull request for that.
My guess is that sinon does some sort of instanceOf
test or something, not sure if this can be solved in a generic way.
I think peer dependency is for this kind of issue. How about making sinon a peerDependency <5.0.0
.
I'd agree that's a good idea. This can be a really time-consuming edge-case, compared to an initial "you have to install sinon yourself"-hint to get it working (in a reliable way).