Skip to content

Commit 0ba2ae2

Browse files
perzyfent
authored andcommitted
feat: support mock prop with getter setter (#4)
* 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
1 parent d08cf4c commit 0ba2ae2

File tree

3 files changed

+129
-12
lines changed

3 files changed

+129
-12
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,28 @@ muk(fs, 'readFile', (path, callback) => {
1919
});
2020
```
2121

22+
Object props mocking with setter/getter.
23+
24+
```js
25+
const muk = require('muk-prop');
26+
27+
const obj = { _a: 1 };
28+
muk(obj, 'a', {
29+
set: function(val) { this._a = val * 2; },
30+
get: function(val) { return this._a; },
31+
});
32+
33+
obj.a = 2;
34+
console.log(obj.a); // 4
35+
```
36+
2237
Check if member has been mocked.
2338

2439
```js
2540
muk.isMocked(fs, 'readFile'); // true
2641
```
2742

28-
Restore all mocked methods after tests.
43+
Restore all mocked methods/props after tests.
2944

3045
```js
3146
muk.restore();

lib/index.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ var cache = new Map();
66

77

88
/**
9-
* Mocks a method of an object.
9+
* Mocks a value of an object.
1010
*
1111
* @param {Object} obj
1212
* @param {string} key
13-
* @param {!Function} method
13+
* @param {!Function|Object} value
1414
*/
15-
var method = module.exports = (obj, key, method) => {
16-
method = method === undefined ? () => {} : method;
15+
var method = module.exports = (obj, key, value) => {
1716
var hasOwnProperty = obj.hasOwnProperty(key);
1817
mocks.push({
1918
obj,
@@ -36,13 +35,22 @@ var method = module.exports = (obj, key, method) => {
3635
}
3736
flag.add(key);
3837

39-
Object.defineProperty(obj, key, {
40-
writable: true,
38+
var descriptor = {
4139
configurable: true,
4240
enumerable: true,
43-
value: method
44-
});
41+
};
42+
43+
if (value && (value.get || value.set)) {
44+
// Default to undefined
45+
descriptor.get = value.get;
46+
descriptor.set = value.set;
47+
} else {
48+
// Without getter/setter mode
49+
descriptor.value = value;
50+
descriptor.writable = true;
51+
}
4552

53+
Object.defineProperty(obj, key, descriptor);
4654
};
4755

4856
/**

test/method-test.js

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,9 @@ describe('Mock property', () => {
115115
assert(!hasOwnProperty(process.env, 'notExistProp'), 'notExistProp is deleted');
116116
});
117117

118-
it('should mock function when method is null', () => {
118+
it('should be undefined when value is not set', () => {
119119
muk(config, 'enableCache');
120-
assert.equal(typeof config.enableCache, 'function', 'enableCache is function');
121-
assert.equal(config.enableCache(), undefined, 'enableCache return undefined');
120+
assert.equal(config.enableCache, undefined, 'enableCache is undefined');
122121
});
123122

124123
it('should mock property on prototype', () => {
@@ -167,6 +166,101 @@ describe('Mock getter', () => {
167166
});
168167
});
169168

169+
describe('Mock value with getter', () => {
170+
var obj = {
171+
a: 1,
172+
};
173+
174+
afterEach(muk.restore);
175+
176+
it('Value are new getter after mocked', () => {
177+
muk(obj, 'a', {
178+
get: () => 2,
179+
});
180+
assert.equal(obj.a, 2, 'property a of obj is 2 with getter');
181+
});
182+
183+
it('Should throw error when getter', () => {
184+
muk(obj, 'a', {
185+
get: () => {
186+
throw new Error('oh no');
187+
}
188+
});
189+
190+
try {
191+
obj.a;
192+
} catch (e) {
193+
assert.equal(e.message, 'oh no')
194+
}
195+
});
196+
197+
it('Should have original getter after muk.restore()', () => {
198+
muk(obj, 'a', {
199+
get: () => 2,
200+
});
201+
202+
muk.restore();
203+
assert.equal(obj.a, 1, 'property a of obj is equal to original');
204+
});
205+
});
206+
207+
describe('Mock value with setter', () => {
208+
var obj = {
209+
_a: 1,
210+
};
211+
212+
Object.defineProperty(obj, 'a', {
213+
configurable: true,
214+
set: function(value) {
215+
this._a = value;
216+
},
217+
get: function() {
218+
return this._a;
219+
},
220+
})
221+
222+
afterEach(muk.restore);
223+
224+
it('Value are new setter after mocked', () => {
225+
muk(obj, 'a', {
226+
set: function(value) {
227+
this._a = value + 1;
228+
},
229+
get: function() {
230+
return this._a;
231+
},
232+
});
233+
obj.a = 2;
234+
assert.equal(obj.a, 3, 'property a of obj is 3 with getter');
235+
});
236+
237+
it('Should throw error when setter', () => {
238+
muk(obj, 'a', {
239+
set: () => {
240+
throw new Error('oh no');
241+
}
242+
});
243+
244+
try {
245+
obj.a = 2;
246+
} catch (e) {
247+
assert.equal(e.message, 'oh no')
248+
}
249+
});
250+
251+
it('Should have original setter after muk.restore()', () => {
252+
muk(obj, 'a', {
253+
set: function(value) {
254+
this._a = value + 1;
255+
},
256+
});
257+
258+
muk.restore();
259+
obj.a = 2;
260+
assert.equal(obj.a, 2, 'property a of obj is equal to original');
261+
});
262+
});
263+
170264
describe('Mock check', () => {
171265

172266
afterEach(muk.restore);

0 commit comments

Comments
 (0)