sinon-chrome
sinon-chrome copied to clipboard
How to override stubbed methods?
Hi, thank you for awesome module!
I have been trying to override a stubbed method provided by sinon-chrome with my implementation to simulate chrome.runtime.lastError
set inside the method.
Is there any officially-recommended way to override stubbed methods?
What I have tried
I'll write down here what I have tried for overriding methods just FYI.
NG: Assigning a function
First, I tried simply overwrite the method with a function by assignment as mentioned in README, but it seemed not working at all.
chrome.runtime.id = 'my_test_id';
chrome.runtime.getURL = function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
};
// FAIL (getURL() returns undefined)
assert.equal(chrome.runtime.getURL("test"), "chrome-extension://my_test_id/test");
This is because stubbed methods are defined by Object.defineProperty
with writable: false
.
NG: sinon.stub()
Second, I tried sinon.stub()
to stub a stubbed method, which sounds complicated. :P
chrome.runtime.id = 'my_test_id';
sinon.stub(chrome.runtime, "getURL", function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
});
// Error
assert.equal(chrome.runtime.getURL("test"), "chrome-extension://my_test_id/test");
And sinon output error:
TypeError: Attempted to wrap undefined property getURL as function
OK but weird: Replace entire namespace object
Third, I tried replacing entire chrome.runtime
namespace object with another one.
chrome.runtime = {
id: "my_test_id",
getURL: function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
}
};
// PASS
assert.equal(chrome.runtime.getURL("test"), "chrome-extension://my_test_id/test");
Although this one could mange to override a namespace including target method, it looks weird and has too much side-effect which is not related to the test.
I don't think this one is ideal, and there should be another way to override stubbed methods easily IMHO.
@io-monad, hi.
Thank you for issue.
Unfortunately, sinon-chrome
does not support chrome api method overriding now.
I am not completely sure that you needs it.
@vitalets what do you think about?
Is not this work?
chrome.runtime.getURL.restore();
sinon.stub(chrome.runtime, "getURL", function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
});
but anyway it also looks not obvious and needs manual reset / restore.
I suggest to add chrome._stub()
method that behave like sinon's one but allows to overwrite stubs.
chrome._stub(chrome.runtime, "getURL", function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
});
Could we update the README? The Difference from 0.2 section makes it sound like we can and should override by assigning the function.
before(function () {
chrome.runtime.id = 'my_test_id';
chrome.runtime.getURL = function (path) {
return 'chrome-extension://' + chrome.runtime.id + '/' + path;
};
});
@tswast you are right, I'll fix readme
Still an issue with sinon-chrome 2.2.1:
'use strict';
const chrome = require('sinon-chrome/extensions');
const originalSet = chrome.proxy.settings.set;
chrome.proxy.settings.set = function () {
console.log('I\'m new here!');
}
console.log('STILL THE SAME?', chrome.proxy.settings.set === originalSet); // Prints "true".
Proposed a pull request: #57
@ilyaigpetrov hi.
I have no reason to add same functionality for api methods, since sinon-chrome@2 has released. You can override all logic behavior , using sinon stubs api.
For define custom logic, like topic starter wants, you should use callsFake method from sinon stub.
I think this issue can be closed, it's now documented: https://github.com/acvetkov/sinon-chrome#stubs-api
Essentially just call .returns()
on the desired method:
chrome.runtime.getManifest.returns({permissions: ['tabs']});