diff --git a/README.md b/README.md index 74954c6..4e585a0 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,28 @@ muk(fs, 'readFile', (path, callback) => { }); ``` +Object props mocking with setter/getter. + +```js +const muk = require('muk-prop'); + +const obj = { _a: 1 }; +muk(obj, 'a', { + set: function(val) { this._a = val * 2; }, + get: function(val) { return this._a; }, +}); + +obj.a = 2; +console.log(obj.a); // 4 +``` + Check if member has been mocked. ```js muk.isMocked(fs, 'readFile'); // true ``` -Restore all mocked methods after tests. +Restore all mocked methods/props after tests. ```js muk.restore(); diff --git a/lib/index.js b/lib/index.js index f072dd0..9591fb6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,14 +6,13 @@ var cache = new Map(); /** - * Mocks a method of an object. + * Mocks a value of an object. * * @param {Object} obj * @param {string} key - * @param {!Function} method + * @param {!Function|Object} value */ -var method = module.exports = (obj, key, method) => { - method = method === undefined ? () => {} : method; +var method = module.exports = (obj, key, value) => { var hasOwnProperty = obj.hasOwnProperty(key); mocks.push({ obj, @@ -36,13 +35,22 @@ var method = module.exports = (obj, key, method) => { } flag.add(key); - Object.defineProperty(obj, key, { - writable: true, + var descriptor = { configurable: true, enumerable: true, - value: method - }); + }; + + if (value && (value.get || value.set)) { + // Default to undefined + descriptor.get = value.get; + descriptor.set = value.set; + } else { + // Without getter/setter mode + descriptor.value = value; + descriptor.writable = true; + } + Object.defineProperty(obj, key, descriptor); }; /** diff --git a/test/method-test.js b/test/method-test.js index 4a11052..ffafea2 100644 --- a/test/method-test.js +++ b/test/method-test.js @@ -115,10 +115,9 @@ describe('Mock property', () => { assert(!hasOwnProperty(process.env, 'notExistProp'), 'notExistProp is deleted'); }); - it('should mock function when method is null', () => { + it('should be undefined when value is not set', () => { muk(config, 'enableCache'); - assert.equal(typeof config.enableCache, 'function', 'enableCache is function'); - assert.equal(config.enableCache(), undefined, 'enableCache return undefined'); + assert.equal(config.enableCache, undefined, 'enableCache is undefined'); }); it('should mock property on prototype', () => { @@ -167,6 +166,101 @@ describe('Mock getter', () => { }); }); +describe('Mock value with getter', () => { + var obj = { + a: 1, + }; + + afterEach(muk.restore); + + it('Value are new getter after mocked', () => { + muk(obj, 'a', { + get: () => 2, + }); + assert.equal(obj.a, 2, 'property a of obj is 2 with getter'); + }); + + it('Should throw error when getter', () => { + muk(obj, 'a', { + get: () => { + throw new Error('oh no'); + } + }); + + try { + obj.a; + } catch (e) { + assert.equal(e.message, 'oh no') + } + }); + + it('Should have original getter after muk.restore()', () => { + muk(obj, 'a', { + get: () => 2, + }); + + muk.restore(); + assert.equal(obj.a, 1, 'property a of obj is equal to original'); + }); +}); + +describe('Mock value with setter', () => { + var obj = { + _a: 1, + }; + + Object.defineProperty(obj, 'a', { + configurable: true, + set: function(value) { + this._a = value; + }, + get: function() { + return this._a; + }, + }) + + afterEach(muk.restore); + + it('Value are new setter after mocked', () => { + muk(obj, 'a', { + set: function(value) { + this._a = value + 1; + }, + get: function() { + return this._a; + }, + }); + obj.a = 2; + assert.equal(obj.a, 3, 'property a of obj is 3 with getter'); + }); + + it('Should throw error when setter', () => { + muk(obj, 'a', { + set: () => { + throw new Error('oh no'); + } + }); + + try { + obj.a = 2; + } catch (e) { + assert.equal(e.message, 'oh no') + } + }); + + it('Should have original setter after muk.restore()', () => { + muk(obj, 'a', { + set: function(value) { + this._a = value + 1; + }, + }); + + muk.restore(); + obj.a = 2; + assert.equal(obj.a, 2, 'property a of obj is equal to original'); + }); +}); + describe('Mock check', () => { afterEach(muk.restore);