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๋ฅผ ์กฐ๋กฑํ๋ ๊ฒ์ด ์ข์ ํ ์คํธ ๋ฐฉ๋ฒ์ธ์ง ์์ ํ ํ์ ํ ์ ์์ต๋๋ค. ํ ์คํธ ๊ธฐ๊ฐ ๋์ ์์ฑ์ ์ผ๋ถ ๊ฐ์ผ๋ก ์ค์ ํ๊ธฐ๋ง ํ๋ฉด ๋๋ถ๋ถ์ ๊ฒฝ์ฐ(?)
์ด์จ๋ ์คํ ์ด ํจ์๊ฐ ์๋ ๊ฐ์ฒด๋ผ๋ฉด ์์ฑ ์ค๋ช ์๋ก ์ทจ๊ธ๋ ๊น์? ๋ค์๊ณผ ๊ฐ์ ๊ฒ:
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')
๊ฐ ๋ฐ์ ํ๋ค๊ณ ์ฃผ์ฅํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๋ฌธ ์ผ์ด ์๋ ํ ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก๋ getter๊ฐ ์ ๊ณต๋์ง๋ง setter๊ฐ ์ ๊ณต๋์ง ์๋ ๊ฒฝ์ฐ์ ๋๋ค. ์ด๋ ์์ฑ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ง๋ค์ด ํ๋ก๋์ ์ฝ๋์๋ ์ข์ ์์ด๋์ด์ผ ์ ์์ง๋ง ํ ์คํธ์ ๋ฐฉํด๊ฐ ๋ฉ๋๋ค. Sinon์ด getter ๋ฐ setter๋ฅผ ์ง์ํ๋ฉด ํด๋น ์ฌ์ฉ ์ฌ๋ก์ ๋ํด ์ด์ผ๊ธฐํ ์ ์์ต๋๋ค.