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 : "개인"과 또 다른 방법 일반적인 문제는 당신이 테스트하려는 경우이다 publicMethod1
와 publicMethod2
와 헬퍼를 조롱 다시, 당신은 일반적으로 그렇게 재배 선 같은 것을해야합니다 . 그러나 별도의 파일에있는 경우 Proxyquire 를 사용 하여 이를 수행 할 수 있습니다. Rewire와 달리 빌드 프로세스를 설명 필요가없고 읽기 및 디버그가 TypeScript에서 작동합니다.
테스트에 개인 메서드를 사용할 수 있도록 다음을 수행합니다.
const _myPrivateMethod: () => {};
const methods = {
myPublicMethod1: () => {},
myPublicMethod2: () => {},
}
if (process.env.NODE_ENV === 'test') {
methods._myPrivateMethod = _myPrivateMethod;
}
module.exports = methods;
'IT' 카테고리의 다른 글
html5 비디오 태그에서 소스 변경 (0) | 2020.07.10 |
---|---|
우분투에서 Java 환경 경로를 설정하는 방법 (0) | 2020.07.10 |
Oracle을 사용하여 선택 (0) | 2020.07.10 |
MAMP에서 PHP 5.5.3 캐싱 중지 (0) | 2020.07.10 |
Node.js 오류 : Express 모듈을 못 견딜 수 없습니다 (0) | 2020.07.10 |