sinon-chrome icon indicating copy to clipboard operation
sinon-chrome copied to clipboard

How to override stubbed methods?

Open io-monad opened this issue 8 years ago • 8 comments

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 avatar Apr 22 '16 23:04 io-monad

@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?

acvetkov avatar Apr 25 '16 09:04 acvetkov

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;
});

vitalets avatar Apr 25 '16 09:04 vitalets

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 avatar Jul 19 '16 17:07 tswast

@tswast you are right, I'll fix readme

acvetkov avatar Jul 19 '16 19:07 acvetkov

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".

ilyaigpetrov avatar May 06 '17 06:05 ilyaigpetrov

Proposed a pull request: #57

ilyaigpetrov avatar May 07 '17 09:05 ilyaigpetrov

@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.

acvetkov avatar May 07 '17 21:05 acvetkov

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']});

fregante avatar Mar 16 '24 11:03 fregante