Sinon: ๋ช…๋ช… ๋œ ์ŠคํŒŒ์ด

์— ๋งŒ๋“  2013๋…„ 02์›” 25์ผ  ยท  13์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: sinonjs/sinon

์ŠคํŒŒ์ด (๊ฐœ์ฒด ์†์„ฑ ์ œ์™ธ)๊ฐ€ ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์–ด์„ค ์…˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์˜ ๊ฐ€๋…์„ฑ์— ๋„์›€์ด๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์žฌ์Šค๋ฏผ ์ŠคํŒŒ์ด๋Š” ์ด๊ฒƒ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

Help wanted

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ์ด๊ฒƒ์„๋ณด๊ณ ์žˆ๋‹ค; ํ•ญ์ƒ ์ด๋ฆ„์ด proxy ๋ผ๊ณ  ํ‘œ์‹œ๋˜์–ด ์žˆ์ง€๋งŒ Object.defineProperty(spy, 'name', { value: 'new name' }) ์ด๋ฉด "new name"์„๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋‹ค์‹œ ์—ด๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  13 ๋Œ“๊ธ€

Sinon์€ ๋ž˜ํ•‘ ๋œ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋นˆ ๋ช…๋ช… ๋œ ํ•จ์ˆ˜๋ฅผ ๋ž˜ํ•‘ํ•˜์—ฌ ์ŠคํŒŒ์ด์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var spy = sinon.spy(function doStuff() {});

์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ๊ธธ์ด์˜ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

var spy = sinon.spy(function doStuff(a, b, c) {}); // spy.length === 3

๋‚ด๊ฐ€ ๋ณผ ์ˆ˜์žˆ๋Š” ํ•œ ํ•ญ์ƒ ํ•จ์ˆ˜ ์ด๋ฆ„์œผ๋กœ "ํ”„๋ก์‹œ"์ž…๋‹ˆ๋‹ค. ์ด ์˜๊ฒฌ์ด ์‚ฌ์‹ค์ž…๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ๋ณผ ์ˆ˜์žˆ๋Š” ํ•œ ํ•ญ์ƒ ํ•จ์ˆ˜ ์ด๋ฆ„์œผ๋กœ "ํ”„๋ก์‹œ"์ž…๋‹ˆ๋‹ค. ์ด ์˜๊ฒฌ์ด ์‚ฌ์‹ค์ž…๋‹ˆ๊นŒ?

์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์˜ˆ์ œ๋ฅผ ๊ฒŒ์‹œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

// test/index.js
var sinon = require('sinon');

var spy = sinon.spy(function doStuff() {
    console.log('Name: ' + spy.name);
});

spy();
โžœ  sinon-test node test/index.js 
Name: proxy

์ด์ „์— ๋ฌด์—‡์„ํ–ˆ๋Š”์ง€ ๊ธฐ์–ต์ด ๋‚˜์ง€ ์•Š์ง€๋งŒ ํ•จ์ˆ˜ ์ด๋ฆ„์ด "proxy"์ธ ํ…Œ์ŠคํŠธ ์‹คํŒจ์—์„œ Mocha ์ถœ๋ ฅ์„ ์–ป์—ˆ์œผ๋ฉฐ "doStuff"๋ผ๋Š” ๊ฒƒ์„ ๋ชจ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ๋ฌด์—‡์ด ์—ˆ๋Š”์ง€ ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ฒŒ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„๋ณด๊ณ ์žˆ๋‹ค; ํ•ญ์ƒ ์ด๋ฆ„์ด proxy ๋ผ๊ณ  ํ‘œ์‹œ๋˜์–ด ์žˆ์ง€๋งŒ Object.defineProperty(spy, 'name', { value: 'new name' }) ์ด๋ฉด "new name"์„๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋‹ค์‹œ ์—ด๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ํ†ตํ•ด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

const mapMethod = sinon.spy(Array.prototype, 'map');
const methodName = map.wrappedMethod.name;
console.log(methodName); // 'map'

ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ์ฝ”๋“œ๊ฐ€ ํ•จ์ˆ˜ ์ด๋ฆ„์— ์˜์กด ํ•  ๋•Œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” @Tbhesswebber .

์•„ ... ์ข‹์€ ์ง€์ ์ด์•ผ. ์ €๋Š” ๊ณ ์ฐจ์› ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฅด์น˜๊ธฐ์œ„ํ•œ ์ปค๋ฆฌํ˜๋Ÿผ์„ ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค ( Array.prototype ๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ ์‚ฌ์šฉ). ์ด๊ฒƒ์ด ์ €๋ฅผ์ด ๋ฌธ์ œ๋กœ ์ด๋Œ์—ˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€!

์ถ”์‹ -ํ…Œ์ŠคํŠธ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์‹ค์ œ๋กœ _ ์‹œ๋„ _ ํ•  ๋•Œ ์ •๋ง ์ง€๋ฃจํ•ฉ๋‹ˆ๋‹ค!

์ด๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์œ ์šฉํ•œ ์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋“ ์ง€ ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋” ๊นŠ์ด ํŒŒ๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฉ‹์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜ ๋œ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์— ์˜์กดํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‚˜ ํ…Œ์ŠคํŠธ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๊ฒฝ์šฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๋…ผ์˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@mroderick ์›๋ณธ์œผ๋กœ ์ŠคํŒŒ์ด๋ฅผ ๋งŒ๋“ค ๋•Œ Object.defineProperty(spy, 'name', { configurable: true, value: spy.wrappedMethod.name }) ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ๊ธฐ๋Šฅ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.-ํ•จ์ˆ˜์— ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜์—ฌ ์ŠคํŒŒ์ด์˜ ์ด๋ฆ„์„ ์ง€์ •-๊ธธ์„ ์žƒ์–ด๋ฒ„๋ฆฐ ๊ฒƒ ๊ฐ™์•„์š”. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋ช…์‹œ ์ ์œผ๋กœ ๋ช…๋ช…ํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ œ์•ˆ์— ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "ํ”„๋ก์‹œ"์ด๋ฆ„๋„ ๋ณ€๊ฒฝํ•ด์•ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ŠคํŒŒ์ด ๊ธฐ๋Šฅ์ด ์›๋ž˜์˜ ๊ธฐ๋Šฅ๊ณผ ์ตœ๋Œ€ํ•œ ๊ฐ€๊น๊ฒŒ ๋ณด์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ arity๋ฅผ โ€‹โ€‹๋ณด์žฅํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

API์—๋„ spy.named(name) ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฉ๊ธˆ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ๐Ÿ˜† ์ŠคํŒŒ์ด์— displayName ์†์„ฑ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ด๋ฆ„๋„ ๋ฐ”๊ฟ”์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ด๊ฑธ๋ณด์„ธ์š”.

# 1987์˜ ํŒจ์น˜๋Š” v7.2.7 ์— ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ชจ๋‘์—๊ฒŒ ๋งŒ์กฑ ์Šค๋Ÿฌ์šด์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค โค๏ธ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰