Sinon: ES5 getter ๋ฐ setter ๋ž˜ํ•‘

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

var o = {
  get foobar() { return 'foobar' },
  set foobar(s) { throw 'bzzt!' },
  foo: function() { return 'foo' },
  bar: 'bar'
}; // -> { foobar: [Getter/Setter], foo: [Function], bar: 'bar' }

sinon.mock(o).expects('foobar').returns('woohoo'); // doesn't because sinon.wrapMethod() does an object[property] which accesses the getter which returns a string

getter ๋ฐ setter๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด ๊ฐœ์ฒด์— ๋Œ€ํ•ด Object.getOwnPropertyDescriptor(obj, prop) ๋ฅผ ์ˆ˜ํ–‰ํ•œ ๋‹ค์Œ ์žฌ๊ท€์  Object.getPrototypeOf(obj) ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋””์Šคํฌ๋ฆฝํ„ฐ์—๋Š” 'get' ๋ฐ 'set' ์†์„ฑ์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ getter ๋˜๋Š” setter ๋˜๋Š” ๋‘˜ ๋‹ค๋ฅผ ์กฐ๋กฑํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ป๊ฒŒ ์ง€์ •ํ•ฉ๋‹ˆ๊นŒ? ์ผ๋ถ€ ์˜ต์…˜:

mock(o).expects('foobar'); // ambiguous, the setter? getter? or both?
mock(o).expects('get foobar'); // ambiguous, there may be a legitimate property named "get foobar"
mock(o).expectsGet('foobar'); // clear but more code in Sinon and more to document ?
mock(o).expectsSet('foobar'); // ditto

๋˜ํ•œ ํ˜„์žฌ ํ™˜๊ฒฝ์— ์—†์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ทœ์น™์ด ์ด๋ฏธ ๋งˆ๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋ˆ„๊ตฐ๊ฐ€ IE6์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

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

๋“œ๋ฌธ ์ผ์ด ์•„๋‹Œ ํ•œ ๊ฐ€์ง€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” getter๊ฐ€ ์ œ๊ณต๋˜์ง€๋งŒ setter๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์†์„ฑ์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๋งŒ๋“ค์–ด ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ์—๋Š” ์ข‹์€ ์•„์ด๋””์–ด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ํ…Œ์ŠคํŠธ์— ๋ฐฉํ•ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Sinon์ด getter ๋ฐ setter๋ฅผ ์ง€์›ํ•˜๋ฉด ํ•ด๋‹น ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๊ท€ํ•˜์˜ ์˜ˆ๋ฅผ ๋ณด๋ฉด getter๋ฅผ ์กฐ๋กฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•์ธ์ง€ ์™„์ „ํžˆ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๊ธฐ๊ฐ„ ๋™์•ˆ ์†์„ฑ์„ ์ผ๋ถ€ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ(?)

์–ด์จŒ๋“  ์Šคํ…์ด ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด๋ผ๋ฉด ์†์„ฑ ์„ค๋ช…์ž๋กœ ์ทจ๊ธ‰๋ ๊นŒ์š”? ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ:

stub(o, "foobar", { get: function () { return 42; } });

๋‚˜๋Š” ๋‹น์‹ ์˜ ๊ธฐ๋Œ€๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ด์•ผ ํ• ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด - ๊ทธ๋Ÿฌ๋‚˜ ์†์„ฑ ์กฐํšŒ์— ๋ชจ์˜ ๊ธฐ๋Œ€๋ฅผ ๋‘๋Š” ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์•„๋งˆ๋„ "์‹ค์ œ"๋ฐฉ๋ฒ•์ด์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?

์˜ˆ์ œ๋Š” ๊ฐ„๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ๋˜ ์‹ค์ œ ์ฝ”๋“œ๋Š” ๋ช‡ ๊ฐ€์ง€๋ฅผ ํ•จ๊ป˜ ์ถ”๊ฐ€ํ•œ get identifier ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ํ…Œ์ŠคํŠธ์—์„œ ๊ท€์ฐฎ๊ฒŒ ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ณณ์—์„œ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค. x.identifier ์— ์•ก์„ธ์Šคํ•œ ๋‹ค์Œ ๋ฐ˜ํ™˜๋œ ํ•ญ๋ชฉ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ getIdentifier() ๋กœ ๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ดœ์ฐฎ์ง€๋งŒ ์•ž์œผ๋กœ ๊ณ„์‚ฐ๋œ ์†์„ฑ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ getter์™€ setter๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ์ด๊ฒƒ์€ Sinon์ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ง ์ด๊ฒƒ์— ๋Œ€ํ•ด ๊ฒฐ์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ์‰ฌ๊ณ  ๋‚˜์ค‘์— ๊ฒฐ์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์˜๊ฒฌ/์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ์—ฌ๊ธฐ์— ์ ์–ด ์ฃผ์‹ญ์‹œ์˜ค.

๋“œ๋ฌธ ์ผ์ด ์•„๋‹Œ ํ•œ ๊ฐ€์ง€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” getter๊ฐ€ ์ œ๊ณต๋˜์ง€๋งŒ setter๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์†์„ฑ์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๋งŒ๋“ค์–ด ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ์—๋Š” ์ข‹์€ ์•„์ด๋””์–ด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ํ…Œ์ŠคํŠธ์— ๋ฐฉํ•ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Sinon์ด getter ๋ฐ setter๋ฅผ ์ง€์›ํ•˜๋ฉด ํ•ด๋‹น ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น๋ถ„๊ฐ„์€ Sinon์—์„œ getter์™€ setter๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ถ„๋ช…ํžˆ, ์ด ๋ฌธ์ œ๊ฐ€ ๋…ผ์˜๋œ ์ง€ ์˜ค๋ž˜๋˜์—ˆ์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์€ ๋งค์šฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค...

+1
๋‚˜๋„ ๊ทธ๋ฆฌ์›Œ. ํŒŒ์ผ ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐœ์ฒด์™€ ๊ฐ™์€ ์ผ๋ถ€ ๊ธฐ๋ณธ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ getter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”์ƒํ™”๋กœ ์ž‘๋™ํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฒŒํ„ฐ๋ฅผ ์Šคํ…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ๋„ ์žฌ๊ฐœ๋ด‰ ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ž˜ํ•‘๋œ ์œ„์น˜ ๊ฐœ์ฒด์˜ ํ•„๋“œ๋ฅผ ์Šคํ„ฐ๋น™ํ•˜๋Š” ๋ฐ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ธฐ๋Šฅ์— +1!

:+1: ์ €๋„ ์ด ๊ธฐ๋Šฅ์˜ ํ•„์š”์„ฑ์„ ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค.

:+1: ๋‹ค์‹œ ์—ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ES6์ด ์žกํžˆ๋ฉด์„œ ์ด๊ฒƒ์€ ๊ทธ ์–ด๋Š ๋•Œ๋ณด๋‹ค ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. expectsGet ๋ณ€ํ˜•์ด ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค.

+1 @simonzack์— ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

+1

์ด๊ฒƒ๋„ ์žฌ๊ฐœ๋ด‰ ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ž˜ํ•‘๋œ ์œ„์น˜ ๊ฐœ์ฒด์˜ ํ•„๋“œ๋ฅผ ์Šคํ„ฐ๋น™ํ•˜๋Š” ๋ฐ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

https://github.com/mroderick/wrapple ์ด ๋‹น์‹ ์„ ์œ„ํ•ด ๊ทธ ๊ฐ„๊ฒฉ์„ ๋ง‰์Šต๋‹ˆ๊นŒ?

์š”์ฆ˜์€ wrapple์„ ์ƒ๋‹นํžˆ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์•„๋งˆ๋„ ๋‹น์‹ ์ด ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ wrapple์ด ํ‹ˆ์„ ๋ง‰์•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

+1์€ getter ์กฐ๋กฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” sinon์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

@derwaldgeist ๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”, Sinon์˜ ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์ตœ์‹  ๋ฒ„์ „์€ sandboxes ๋ฐ sinon.stub ๋ชจ๋‘๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ„ฐ๋น™ ๊ฒŒํ„ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

get ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ

var myObj = {
    prop: "foo"
};

createStub(myObj, "prop").get(function getterFn() {
    return "bar";
});

myObj.prop // "bar"

์ด๊ฒƒ์ด ๊ท€ํ•˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ํ•ฉํ•œ์ง€ ๋˜๋Š” ๋” ์˜์‹ฌ๋˜๋Š” ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋นจ๋ฆฌ ๋Œ์•„์™€ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ ‡๊ฒŒ ์ •์˜๋œ getter๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณต์›ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด sinon์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ณด์•˜์ง€๋งŒ get()์„ ํ˜ธ์ถœํ•  ๋•Œ ์›๋ž˜ getter๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋ณผ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @derwaldgeist ์ž…๋‹ˆ๋‹ค .

์Šคํ…๋˜๊ธฐ ์ „์— ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ getter๋ฅผ ๋ณต์›ํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ ์Šคํ…์—์„œ restore ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ

var myObj = {
    prop: "foo"
};

var stub = createStub(myObj, "prop");

stub.get(function getterFn() {
    return "baz";
});

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

stub ๋ฉ”์„œ๋“œ ์ž์ฒด(๋น„ํ•จ์ˆ˜ ์†์„ฑ์„ ์Šคํ„ฐ๋น™ํ•  ๋•Œ) ๋˜๋Š” wrapMethod ์œ ํ‹ธ๋ฆฌํ‹ฐ ์— ์ด restore ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค .

์™€, ๋น ๋ฅด๋„ค์š”. ๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹œ๋„ํ–ˆ๋‹ค :

 const stub = sinon.stub(myObj, 'prop');
 stub.get(() => ({}));
  ...
 stub.restore();

๊ทธ๋Ÿฌ๋‚˜ restore()๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. Cannot redefine property: prop

createStub ๋ฐฉ๋ฒ•์€ ์–ด๋””์—์„œ ์™”์Šต๋‹ˆ๊นŒ?

@derwaldgeist ํ…Œ์ŠคํŠธ์—์„œ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ํŽธ์ง‘ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์–ด์จŒ๋“  sinon.stub ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์ œ๊ฐ€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์–ด๋–ค ๋ฒ„์ „์˜ sinon์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

configurable: true ์—†์ด ์ •์˜๋œ ์†์„ฑ์œผ๋กœ ์ธํ•ด ์†์„ฑ์„ ๋ณต์›ํ•  ์ˆ˜ ์—†์–ด์„œ ํ•ด๋‹น ์„ค๋ช…์ž๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•œ ์ตœ์‹  ๋ฒ„์ „์„ ์•„์ง ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@derwaldgeist์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” _์ƒ๊ฐ__ v4๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ผ๋ถ€ ๋‹ค๋ฅธ dep๊ฐ€ v1.7์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด์„œ ์–ด๋Š ๊ฒƒ์ด _์‹ค์ œ๋กœ_ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์— ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” sinon.version ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

@jshado1 ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ์ฃผ์š” ๋ฒ„์ „์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ๋ณ€๊ฒฝ ๋กœ๊ทธ ๋˜๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„์ „ 4์˜ ๊ฒฝ์šฐ sinon.stub({}, 'nonExistingProperty') ๊ฐ€ ๋ฐœ์ƒ ํ•œ๋‹ค๊ณ  ์ฃผ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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