2013-06-14 3 views
9

드러난 모듈 패턴과 잠깐의 로맨스를 쓴 후에 단위 테스트 모듈에 관해서는 뒤늦게 깨달았습니다. 그러나 모듈 테스트에 대한 내 접근 방식인지 또는 어떤 형태의 해결 방법이 있는지 여부를 결정할 수는 없습니다. 나는 (재스민 사용) publicMethodB에 publicMethodA 통해 선도하는 다양한 경로를 테스트하고 싶었모듈 패턴 노출 - 재스민을 이용한 단위 테스트

var myWonderfulModule = (function() { 
    function publicMethodA (condition) { 
    if(condition === 'b') { 
     publicMethodB(); 
    } 
    } 

    function publicMethodB() { 
    // ... 
    } 

    return { 
    methodA : publicMethodA, 
    methodB : publicMethodB 
    } 
}()); 

:

는 다음과 같은 코드를 생각해 보자. 나는 작은 시험과 같이 작성할 수 있습니다

it("should make a call to publicMethodB when condition is 'b'", function() { 
    spyOn(myWonderfulModule , 'publicMethodB'); 
    myWonderfulModule.publicMethodA('b'); 
    expect(myWonderfulModule.publicMethodB).toHaveBeenCalled(); 
}); 

만약 내가 제대로 이해하고, 변경할 수 없습니다 폐쇄 내 publicMethodB의 사본이있다. 내가 나중에 myWonderfulModule.publicMethodB을 변경하더라도 : myWonderfulModule.publicMethodA를 호출

myWonderfulModule.publicMethodB = undefined; 

는 여전히 B.

의 원본 버전을 실행

위의 예는 물론 간단하다하지만 난 곳을 생각할 수있는 시나리오가 많이 있습니다 메소드를 통해 조건부 경로를 단위 테스트하는 것이 편리합니다.

이것은 노출 모듈 패턴의 제한입니까 아니면 단순히 단위 테스트의 오용입니까? 어떤 해결 방법을 사용할 수 없습니까? RequireJS와 같은 것으로 이동하거나 비 모듈 코드로 되돌아 갈 것을 고려 중입니다.

감사합니다.

답변

8

클로저의 인턴 방법을 테스트 할 수 없습니다. 그리고 너는 그것에 대해서도 스파이가되어서는 안된다. 모듈에 대해 블랙 박스로 생각하십시오. 당신은 무언가를 넣으면 무언가를 얻습니다. 테스트해야 할 것은 모듈에서 얻은 것이 예상 한 것입니다.

모듈의 메소드를 감시하는 것은별로 중요하지 않습니다. 그것에 대해 생각해보십시오. 당신이 스파이 일 때, 시험은 통과됩니다. 이제는 버그를 생성하는 기능을 변경하고, 테스트는 여전히 통과하지만 함수는 여전히 호출되지만 버그는 언급하지 않습니다. 내부 메쏘드의 원인을 간첩 할 필요가 없다는 것을 테스트한다면, 모듈의 결과가 기대하는 것일 때 불리는 것입니다.

그래서 귀하의 경우에는 들어가서 아무것도 나오지 않습니다. 이것은별로 의미가 없지만 귀하의 모듈이 DOM과 상호 작용하거나 ajax 호출을한다고 믿습니다. 이것은 당신이 테스트 할 수있는 것들 (DOM)이거나 당신이 스파이 (ajax)를해야한다는 것입니다.

또한 Inversion of Control and Dependency Injection에 익숙해 져야합니다. 이것들은 모듈을 훨씬 더 쉽게 테스트 할 수있게 해주는 패턴입니다.

0

publicMethodA()에서 publicMethodB()를 호출 할 때 키워드 "this"를 사용하면 작동합니다. 예 :

var myWonderfulModule = (function() { 
    function publicMethodA (condition) { 
     if(condition === 'b') { 
      this.publicMethodB(); 
     } 
    } 

    function publicMethodB() { 
     // ... 
    } 

    return { 
     methodA : publicMethodA, 
     methodB : publicMethodB 
    } 
}()); 
관련 문제