diff --git a/package.json b/package.json index fbfc3d5..62877da 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@types/lodash": "*", "@types/node": "*", "@types/sinon": "*", + "sinon": "^9.0.2", "lodash": "^4.17.13", "mock-stdin": "^1.0.0", "nock": "^13.3.3", @@ -24,7 +25,6 @@ "http-call": "^5.2.3", "markdown-toc": "^1.2.0", "mocha": "^5.2.0", - "sinon": "^9.0.2", "ts-node": "^9.0.0", "tslib": "^2.6.2", "typescript": "4.4.3" diff --git a/src/stub.ts b/src/stub.ts index 3ff293e..975cada 100644 --- a/src/stub.ts +++ b/src/stub.ts @@ -1,32 +1,26 @@ -import * as _ from 'lodash' +import * as sinon from 'sinon' -// eslint-disable-next-line valid-jsdoc /** * mocks an object's property */ -export default function (object: T, path: K, value: () => T[K]) { - if (object === undefined || path === undefined) throw new Error('should not be undefined') +export default function ( + object: T, + path: K, + fn: (stub: sinon.SinonStub) => sinon.SinonStub, +) { + if (object === undefined || path === undefined) + throw new Error('should not be undefined') + + let stub: sinon.SinonStub return { - run(ctx: {stubs: any[]}) { - ctx.stubs = ctx.stubs || [] - const descriptor = Object.getOwnPropertyDescriptor(object, path) - if (descriptor && descriptor.get) { - ctx.stubs.push(descriptor.get) - descriptor.get = value - Object.defineProperty(object, path, descriptor) - } else { - ctx.stubs.push(_.get(object, path)) - _.set(object, path, value) - } - }, finally(ctx: {stubs: any[]}) { - const stub = ctx.stubs.pop() - const descriptor = Object.getOwnPropertyDescriptor(object, path) - if (descriptor && descriptor.get) { - descriptor.get = stub - Object.defineProperty(object, path, descriptor) - } else { - _.set(object, path, stub) + run(ctx: { sandbox: sinon.SinonSandbox }) { + if (!ctx.sandbox) { + ctx.sandbox = sinon.createSandbox() } + stub = fn(ctx.sandbox.stub(object, path)) + }, + finally() { + stub.restore() }, } } diff --git a/test/stub.test.ts b/test/stub.test.ts index f985845..74857be 100644 --- a/test/stub.test.ts +++ b/test/stub.test.ts @@ -1,7 +1,5 @@ // tslint:disable no-console -import * as sinon from 'sinon' - import {expect, fancy} from '../src' const os = require('os') @@ -16,13 +14,13 @@ const mrGetter = { describe('stub', () => { // from readme fancy - .stub(os, 'platform', () => 'foobar') + .stub(os, 'platform', stub => stub.callsFake(() => 'foobar')) .end('sets os', () => { expect(os.platform()).to.equal('foobar') }) fancy - .stub(os, 'platform', sinon.stub().returns('foobar')) + .stub(os, 'platform', stub => stub.callsFake(() => 'foobar')) .end('uses sinon', () => { expect(os.platform()).to.equal('foobar') expect(os.platform.called).to.equal(true) @@ -38,7 +36,7 @@ describe('stub', () => { fancy .stdout() - .stub(mrGetter, 'foo', () => 2) + .stub(mrGetter, 'foo', stub => stub.get(() => 2)) .end('resets getter', output => { console.log(mrGetter.foo) expect(output.stdout).to.equal('2\n')