Sinon: ๋…๋ฆฝ ์‹คํ–‰ํ˜• ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ธฐ๋Šฅ์„ ์Šคํ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

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

๋งŽ์€ ๋…ธ๋“œ ๋ชจ๋“ˆ์€ ๋‹จ์ผ ํ•จ์ˆ˜(์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฒ”์šฉ "์œ ํ‹ธ๋ฆฌํ‹ฐ" ํ•จ์ˆ˜)๋ฅผ "module.exports"๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค. Sinon.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋…๋ฆฝํ˜• ํ•จ์ˆ˜๋ฅผ ์Šคํ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

// some module, "sum.js" that's "required" throughout the application
module.exports = function(a, b) {
    return a + b;
};

// test.js
var sum = require('sum');
...

beforeEach(function() {
    sumStub = sinon.stub(sum);
    // throws: TypeError: Attempted to wrap undefined property undefined as function
});

afterEach(function() {
   sumStub.restore();
});
...

์ด๊ฒƒ์„ ๋‹ฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

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

์ด ์‹œ๋„

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

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

๋ถˆํ–‰ํžˆ๋„.

npm์˜ ๊ฒฝ์šฐ https://github.com/thlorenz/proxyquire ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Michael Feathers๋Š” ์ด๊ฒƒ์„ ๋งํฌ ์†”๊ธฐ ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

์šฐ์•„ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ผ๋‹จ ๊ทธ ์ž๋ฆฌ์— ์žˆ์œผ๋ฉด ํ‰์†Œ์ฒ˜๋Ÿผ Sinon์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ ์•„ํ‚คํ…์ฒ˜๋ฅผ _๊ฐ์ฒด ์ด์Œ์ƒˆ_๋กœ ์ด๋™ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์˜ค๋Š˜๋‚ ์—๋Š” ์ž‘๋™ํ•˜๋Š” ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. RequireJS์— ๋Œ€ํ•œ ์œ ์‚ฌํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

function MyFunction(){}
module.exports = function(){ return module.exports.MyFunction.apply(this, arguments) }
module.exports.MyFunction = MyFunction

๊ทธ๋Ÿฐ ๋‹ค์Œ require('./MyFunction').MyFunction์„ ์Šคํ…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋Š” ๋ณ€๊ฒฝ ์—†์ด ์Šคํ…๋œ ๋ฒ„์ „์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

: ํ˜„๊ธฐ์ฆ: : ํ˜„๊ธฐ์ฆ ๋‚˜๋Š” ์–ผ๊ตด: : ํ˜„๊ธฐ์ฆ:

์š”์ „๋‚  ๋˜‘๊ฐ™์€ ์ผ์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ•˜์—ฌ ๋‚ด๊ฐ€ ํ•œ ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const proxyquire = require('proxyquire')
const sinon = require('sinon')
const sum = sinon.stub()

const ModuleWithDependency = proxyquire('module', {
  'sum': sum
})

์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์— ๊ฝค ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

CommonJS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

const myStubbedModule = function( absoluteModulePath ) {
  const stub = sinon.stub();
  require.cache[ require.resolve( absoluteModulePath ) ] = stub;
  return stub;
}

_์ฐธ๊ณ _: ํŠธ๋žœ์ŠคํŒŒ์ผ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

require.cache[ require.resolve( absoluteModulePath ) ] = {
  default: stub,
  exports: stub
}

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

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด proxyquire, mock-require , &c๋ฅผ ํ†ตํ•ด ๋…ธ๋“œ ๋ชจ๋“ˆ ๊ณ„์ธต์—์„œ ํ•ดํ‚น์„ ํ•˜๋„๋ก ๋ฐ€์–ด๋ถ™์ธ ์—ฌ๋Ÿฌ ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘์€ ๊ฐ„๋‹จํ•˜๊ณ  ๋œ ๊นŒ๋‹ค๋กœ์šด ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์Šคํ…์„ ์–ป๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ค์šด ๋„์ „์ด ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์„ค์ • ์ค‘์— ์ œ์ž๋ฆฌ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. proxyquire๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์˜ ๋งˆ์ดํฌ๋กœ/ํ”ฝ์Šค์ฒ˜ ํฌ๊ธฐ ๋ฒ„์ „, ์ตœ์ƒ์œ„ ์ˆ˜์ค€ ๋ฐ ๋ชจ๋“  ์Šคํ…์ด ๋กœ๋“œ๋˜๋Š” ๋™์•ˆ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฅผ ๋…ธ๋“œ ๋ชจ๋“ˆ ์ˆ˜์ค€์ด ์•„๋‹Œ JS ์–ธ์–ด ์ˆ˜์ค€์—์„œ ๊ณ„์† ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•˜๊ณ  ์œ„ํ—˜ํ•˜์ง€ ์•Š๊ณ  ์ผ๊ด€๋˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค(์ฃผ์˜ ์‚ฌํ•ญ: ๋ณต์›ํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๋Š” ํ•œ).

์ด ๋ชจ๋“ˆ์„ ๋” ์‰ฝ๊ฒŒ ์Šคํ… ๋ชจ๋“ˆ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/caiogondim/stubbable-decorator.js

๋‚˜๋Š” ๋ฐฉ๊ธˆ Sinon์„ ๊ฐ€์ง€๊ณ  ๋†€๊ณ  ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ '์ธ์ˆ˜'๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

const sumStub = sinon.stub(sum, 'arguments');
sumStub.withArgs(2, 2).returns(4);
sumStub.withArgs(3, 3).returns(6);

์ด ์‹œ๋„

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

@harryi3t - ์ €๋ฅผ ์œ„ํ•ด ์ผํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@harryi3t ES ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ์ €์—๊ฒŒ๋Š” ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
์˜ค๋ฅ˜: can't redefine non-configurable property "default"

@elliottregan ES ๋ชจ๋“ˆ์€ STANDARD์— ๋”ฐ๋ผ ์Šคํ…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋™์ž‘์„ ์—ฌ๊ธฐ์—์„œ ๋…ผ์˜ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์—ฌ์ „ํžˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ES ๋ชจ๋“ˆ์„ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š๊ณ  (Webpack/Babel ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ) ES ๋ชจ๋“ˆ์„ ํŠธ๋žœ์ŠคํŒŒ์ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ES5๋Š” ๊ฒŒํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ES ๋ชจ๋“ˆ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์—๋ฎฌ๋ ˆ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์—ฐ๊ฒฐ๋œ ์Šค๋ ˆ๋“œ์—์„œ ์ œ์•ˆํ•œ ๊ฐ„๋‹จํ•œ ๊ฒฝ๋กœ๋ฅผ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค. mocha --register ... ์€(๋Š”) ๋จผ ๊ธธ์„ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

(function (defineProperty) {
    Object.defineProperty = (obj, prop, desc) => {
        desc.configurable = true;
        return defineProperty(obj, prop, desc);
    };
})(Object.defineProperty);

@Sujimoshi ์ •ํ™•ํžˆ ๋ฌด์—‡์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•? ๋‹น์‹ ์˜ ์ˆ˜์ •์— ๋Œ€ํ•œ ์ปจํ…์ŠคํŠธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋˜ํ•œ ์‚ฌ๋žŒ๋“ค์€ ์ˆ˜์ • ์‚ฌํ•ญ์„ ์–ด๋””์— ๋‘๊ฒ ์Šต๋‹ˆ๊นŒ? ํ˜„์žฌ์˜ ํ™”์‹ ์—์„œ๋Š” ๋„์›€์ด ๋˜๊ธฐ์— ์ •๋ณด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ๋น ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ์›๋ž˜ ์งˆ๋ฌธ์— ๋„์›€์ด๋˜์ง€ ์•Š์œผ๋ฉฐ ES Modules์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Webpack 4์—์„œ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. (๋„๊ตฌ ์ฒด์ธ์— ๋”ฐ๋ผ ๋‹ค๋ฆ„) ES5๋กœ _transpiled_๋œ ES2015+ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. .

์ด ์‹œ๋„

import * as sum from './sum'
sinon.stub(sum, 'default', () => {
  // stubbed function
});

์ง€๊ธˆ์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฐฉ๊ธˆ ES6 ๋ชจ๋“ˆ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

export default const doCoolStuff = () => {
  // do the cool stuff...
}

์ด์—:

export default {
  doCoolStuff: () => {
    // do the cool stuff...
  }
} 

์•ฝ๊ฐ„ ํˆฌ๋ฐ•ํ•˜์ง€๋งŒ ์Šคํ…์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ž˜ํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์ด ๊ฑฐ์˜ 2021๋…„์ธ๋ฐ ๊ฐ€๋Šฅํ• ๊นŒ์š”?

์ง€๊ธˆ์ด ๊ฑฐ์˜ 2021๋…„์ธ๋ฐ ๊ฐ€๋Šฅํ• ๊นŒ์š”?

2019๋…„๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.
ES ๋ชจ๋“ˆ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ CommonJS๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ JavaScript๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

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