IT

mocha 및 node.js를 사용하여 개인 함수의 단위 테스트

lottoking 2020. 7. 10. 07:45
반응형

mocha 및 node.js를 사용하여 개인 함수의 단위 테스트


node.js로 내부 응용 프로그램을 단위 테스트하기 위해 mocha를 사용하고 있습니다.

모듈로 내 보내지 않은 함수를 단위 테스트 할 수 있는지 궁금합니다.

예 :

나는 이와 같이 정의 된 많은 기능을 가지고있다. foobar.js

function private_foobar1(){
    ...
}

function private_foobar2(){
    ...
}

공개로 내 보낸 몇 가지 함수 :

exports.public_foobar3 = function(){
    ...
}

테스트 케이스는 다음과 같이 구성됩니다.

describe("private_foobar1", function() {
    it("should do stuff", function(done) {
        var stuff = foobar.private_foobar1(filter);
        should(stuff).be.ok;
        should(stuff).....

private_foobar1내 보내지 분명히 작동하지 않습니다 .

개인 메소드를 단위 테스트하는 올바른 방법은 무엇입니까? 모카에는 기본 제공 방법이 있습니까?


모듈에서 함수를 내 보내지 언어 모듈 외부의 테스트 코드로 함수를 호출 할 수 없습니다. 이는 자바 스크립트가 작동하는 방식 때문이며 Mocha 자체로드가 피할 수 없습니다.

개인 함수 테스트가 옳은 일이라고 결정한 몇 가지 경우, 내가 한 것은 모듈이 테스트 설정에서 실행 중인지 여부를 확인하기 위해 확인하는 환경 변수를 설정하는 것입니다. 테스트 설정에서 실행 가능 테스트 중에 호출 할 수있는 추가 기능을 내 보냅니다.

여기서 "환경"이라는 단어가 느슨하게 사용되었습니다. 이는 process.env"지금 테스트 중입니다"라는 모듈과 통신 할 수있는 검사 또는 다른 것을 의미 할 수 있습니다. 내가해야하는 인스턴스는 RequireJS 환경에 사용할 module.config목적으로 사용 합니다.


배선 모듈을 점검하십시오 . 모듈 내에서 개인 변수와 함수를 얻거나 조작 할 수 있습니다.

따라서 귀하의 경우 사용은 다음과 가변적입니다.

var rewire = require('rewire'),
    foobar = rewire('./foobar'); // Bring your module in with rewire

describe("private_foobar1", function() {

    // Use the special '__get__' accessor to get your private function.
    var private_foobar1 = foobar.__get__('private_foobar1');

    it("should do stuff", function(done) {
        var stuff = private_foobar1(filter);
        should(stuff).be.ok;
        should(stuff).....

다음은 블로그의 Google 엔지니어 인 필립 월튼 (Philip Walton)이 훌륭한 워크 플로우 입니다.

원리

  • 샘플 코드 작성
  • 메소드를 별도의 코드 블록으로 객체에 바인딩 _하고 예를 들어
  • 시작 및 종료 주석으로 해당 코드 블록을 둘러 쌉니다.

그런 다음 빌드 작업 또는 자체 빌드 시스템 (예 : grunt-strip-code)을 사용하여 빌드를 위해 빌드 작업 또는 제거.

테스트 빌드는 개인 API에 액세스 할 수있는 빌드는 액세스 할 수 없습니다.

단편

다음과 같이 코드를 작성하십시오.

var myModule = (function() {

  function foo() {
    // private function `foo` inside closure
    return "foo"
  }

  var api = {
    bar: function() {
      // public function `bar` returned from closure
      return "bar"
    }
  }

  /* test-code */
  api._foo = foo
  /* end-test-code */

  return api
}())

그리고 그런 거친 작업

grunt.registerTask("test", [
  "concat",
  "jshint",
  "jasmine"
])
grunt.registerTask("deploy", [
  "concat",
  "strip-code",
  "jshint",
  "uglify"
])

더 깊은

이후 기사 에서 "비공개 메소드 테스트"의 "이유"에 대해 설명합니다.


단순하게 유지하고 게재되는 프라이빗 멤버도 추천십시오. 그러나 몇 가지 규칙을 사용하여 공용 API와 명확하게 분리하십시오. 예를 들어 접두사를 붙이 _거나 하나의 개인 개체 아래 에 중첩하십시오 .

var privateWorker = function() {
    return 1
}

var doSomething = function() {
    return privateWorker()
}

module.exports = {
    doSomething: doSomething,
    _privateWorker: privateWorker
}

이 목적을 위해 유용한 npm 패키지를 만들었습니다. 요구에서

기본적으로 다음과 같은 방법으로 비공개 메소드를 노출합니다.

module.testExports = {
    private_foobar1: private_foobar1,
    private_foobar2: private_foobar2,
    ...
}

참고 : 원하는 testExports모든 유효한 이름이 가능 exports합니다.

그리고 다른 모듈에서 :

var requireFrom = require('require-from');
var private_foobar1 = requireFrom('testExports', './path-to-module').private_foobar1;

내부 ()라는 이름의 추가 함수를 추가하고 거기에서 모든 개인 함수를 반환합니다. 그런 다음 내부 () 함수를 내 보냅니다. 예 :

function Internal () {
  return { Private_Function1, Private_Function2, Private_Function2}
}

// Exports --------------------------
module.exports = { PublicFunction1, PublicFunction2, Internal }

다음과 같이 내부 함수를 호출 할 수 있습니다.

let test = require('.....')
test.Internal().Private_Function1()

이 솔루션을 가장 좋아하는 이유는 다음과 같습니다.

  • 항상 내부 () 함수 하나만 내 보냅니다. 내부 () 함수는 항상 개인 함수를 테스트하는 데 사용됩니다.
  • 구현이 간단합니다.
  • 생산 코드에 유해한 영향이 적음 (추가 기능 하나만)

나는 다음 @barwin 대답 및 단위 테스트가 함께 할 수있는 방법을 재배 선 된 모듈. 이 솔루션이 작동하는지 확인할 수 있습니다.

모듈은 공개와 비공개의 두 부분으로 구성되어야합니다. 공용 기능의 경우 표준 방식으로 수행 할 수 있습니다.

const { public_foobar3 } = require('./foobar');

비공개 범위의 경우 :

const privateFoobar = require('rewire')('./foobar');
const private_foobar1 = privateFoobar .__get__('private_foobar1');
const private_foobar2 = privateFoobar .__get__('private_foobar2');

주제에 대해 더 많이 알기 위해 전체 테스트 모듈로 작업 예제를 만들었습니다. 테스트에는 비공개 및 공개 범위가 포함됩니다.

내용 자세한 은 주제를 자세히 설명하는 기사 ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ) 를 확인 하시기 바랍니다 . 여기에는 코드 샘플이 포함되어 있습니다.


나는 그것이 반드시 당신이 찾고있는 대답이 아니라는 것을 알고 있습니다, 내가 대부분의 경우 개인 함수가 테스트 할 가치가있는 것입니다.

예를 들어 다음과 같이 공용 파일과 동일한 파일에 개인 메소드를 대신 ...

src / 사물 / PublicInterface.js


function helper1 (x) {
    return 2 * x;
}

function helper2 (x) {
    return 3 * x;
}

export function publicMethod1(x) {
    return helper1(x);
}

export function publicMethod2(x) {
    return helper1(x) + helper2(x);
}

... 다음과 같이 분할합니다.

src / 사물 / PublicInterface.js

import {helper1} from './internal/helper1.js';
import {helper2} from './internal/helper2.js';

export function publicMethod1(x) {
    return helper1(x);
}

export function publicMethod2(x) {
    return helper1(x) + helper2(x);
}

src / 사물 / 내부 / helper1.js

export function helper1 (x) {
    return 2 * x;
}

src / 사물 / 내부 / helper2.js

export function helper2 (x) {
    return 3 * x;
}

이렇게 하면 Rewire 기타 "마법"을 사용하지 않고 쉽게 테스트 helper1하고있는 helper2그대로 사용할 수 있습니다 (내가 발견 한 바에 따른다고하는 동안 동안 쉽게 테스트 하고 있습니다. TypeScript로 이동하려고 할 때 더 좋지 않은 것은 말할 것도 없습니다. 의 이해 가능성). 하위 폴더라는 internal또는 이와 유사한 폴더에 있으면 의도하지 않은 장소에서 실수로 파일을 사용하는 것을 방지 할 수 있습니다.


PS : "개인"과 또 다른 방법 일반적인 문제는 당신이 테스트하려는 경우이다 publicMethod1publicMethod2와 헬퍼를 조롱 다시, 당신은 일반적으로 그렇게 재배 선 같은 것을해야합니다 . 그러나 별도의 파일에있는 경우 Proxyquire사용 하여 이를 수행 할 수 있습니다. Rewire와 달리 빌드 프로세스를 설명 필요가없고 읽기 및 디버그가 TypeScript에서 작동합니다.


테스트에 개인 메서드를 사용할 수 있도록 다음을 수행합니다.

const _myPrivateMethod: () => {};

const methods = {
    myPublicMethod1: () => {},
    myPublicMethod2: () => {},
}

if (process.env.NODE_ENV === 'test') {
    methods._myPrivateMethod = _myPrivateMethod;
}

module.exports = methods;

참고 URL : https://stackoverflow.com/questions/22097603/unit-testing-of-private-functions-with-mocha-and-node-js

반응형