3

A Sinon sandbox (or sinon instance) is passed from outside to script scope. Internal function (not a method) can be optionally spied/stubbed with Sinon sandbox.

Sinon is involved in some kind of monkey-patching here (not unit-testing) .Sinon sandbox concept fitted the use case really well - until this moment.

I proceed from the fact that function spy cannot be replaced with method spy. It is not a perfect scenario but the design cannot be changed.

const originalCallback = callback;

callback = sinonSandbox.spy(callback);
thirdPartyFn(callback);

// how can this be achieved?
// sinonSandbox.onRestore(() => thirdPartyFn(originalCallback));

How can the app be notified when sandbox is restored to restore spied function? Is there a hook to be launched on 'restore' event? Are there third-party Sinon extensions that may help?

Estus Flask
  • 206,104
  • 70
  • 425
  • 565

3 Answers3

1

I'd mock/stub the restore function :

var originalRestore = sinonSandbox.restore;

sinonSandBox.restore = () => {
  originalRestore();
  // insert code here
};
LoremIpsum
  • 4,328
  • 1
  • 15
  • 17
  • I hoped to avoid this, but yes, it looks like it's all about monkey-patching. Btw, I believe it should be `originalRestore.call(sinonSandbox)` (not sure about arguments, but it looks like `restore` doesn't have some). – Estus Flask Jun 10 '16 at 21:36
1

Originally, sinon doesn't publish any events or offer any hooks, but you can create one:

var spyInstance = sinonSandbox.spy(callback);

(function (original) {

    spyInstance.restore = function() {
        original.apply(this, arguments); // call the original restore function
        events.publish("sinon", "restore-end"); // publish the event to decouple this module from receiving module
    }

})(spyInstance.restore);

then, somewhere down the line in another module:

events.subscribe("sinon", "restore-end", function() {
    // call some code to execute when the sinon spy is restored
});

events object is just your global pub/sub module or something like that.

andree
  • 3,084
  • 9
  • 34
  • 42
0

As it appears, Sinon doesn't have a mechanism for notification on sandbox restore. Since the job of sandbox.restore() is to call restore method on each faked function, I've ended with patching fake's own restore as the most suitable solution:

const originalCallback = callback;
callback = sinonSandbox.spy(callback);

const originalRestore = callback.restore;
callback.restore = function (...args) {
  originalRestore.apply(this, args);
  thirdPartyFn(originalCallback);
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565