Skip to content

Commit

Permalink
feat: support mock prop with getter setter (#4)
Browse files Browse the repository at this point in the history
* feat: support mock prop with getter setter

* feat: add logic check

* feat: add unittest

* unittest: add throw error case

* feat: typo

* feat: refactor && add setter unittest case

* feat: code format

* feat: without set the default value

* feat: add getter/setter example

* feat: update readme

* Update readme with shorter example

* More succinct
  • Loading branch information
perzy authored and fent committed Mar 26, 2018
1 parent d08cf4c commit 0ba2ae2
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 12 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
24 changes: 16 additions & 8 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
};

/**
Expand Down
100 changes: 97 additions & 3 deletions test/method-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0ba2ae2

Please sign in to comment.