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
내 보내지 않기 때문에 분명히 작동하지 않습니다 .
개인 메소드를 단위 테스트하는 올바른 방법은 무엇입니까? 모카에는 기본 제공 방법이 있습니까?
답변
모듈에서 함수를 내 보내지 않으면 모듈 외부의 테스트 코드로 함수를 호출 할 수 없습니다. 이는 JavaScript가 작동하는 방식 때문이며 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"
])
더 깊은
후반 기사에서는 “비공개 메소드 테스트”의 “이유”에 대해 설명합니다.
답변
당신은 간단하게하기 원하는 경우, 단지뿐만 아니라 private 멤버를 내보낼 수 있지만, 분명히으로 어떤 규칙으로 공개 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;
답변
Internal () 이라는 추가 함수를 추가하고 거기에서 모든 개인 함수를 반환합니다. 그런 다음 이 Internal () 함수를 내 보냅니다. 예:
function Internal () {
return { Private_Function1, Private_Function2, Private_Function2}
}
// Exports --------------------------
module.exports = { PublicFunction1, PublicFunction2, Internal }
다음과 같이 내부 함수를 호출 할 수 있습니다.
let test = require('.....')
test.Internal().Private_Function1()
나는이 솔루션을 가장 좋아합니다.
- Internal () 함수 는 항상 하나만 내보내집니다. 이 Internal () 함수는 항상 개인 함수를 테스트하는 데 사용됩니다.
- 구현이 간단합니다
- 생산 코드에 대한 영향이 적음 (한 가지 추가 기능 만)
답변
@ barwin answer에 따라 단위 테스트를 수행하는 방법을 확인했습니다. 재배 선 된 모듈. 이 솔루션이 간단하게 작동하는지 확인할 수 있습니다.
모듈은 공용 및 개인의 두 부분으로 구성되어야합니다. 공용 함수의 경우 표준 방식으로 수행 할 수 있습니다.
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 ) 를 확인하는 것이 좋습니다 . 여기에는 코드 샘플이 포함되어 있습니다.