2015-01-27 2 views
5

테스트 벨로우즈가 1을 반환해야하므로 $rootScope.$broadcast.reset();이 제대로 작동하지 않는 것으로 보입니다. 그러나 각 테스트 케이스마다 $broadcast을 재설정하기 위해 코드를 사용하고 있습니다. 그것은 6.andCallThrough()를 사용하는 동안 각 테스트 케이스마다 브로드 캐스트() 재설정

전에 내가 andCallThrough() 기능없이 사용하기 때문에 이것에 대한 이유는, andCallThrough() 것 같다 반환하지만 일부 리팩터링 후에는 TypeError: Cannot read property 'defaultPrevented' of undefined 것을 나에게 오류를 준, 그래서 그 오류를 방지하기 위해 사용했다.

질문은 andCallThrough을 사용하는 동안 broadcast을 어떻게 재설정 할 수 있습니까? 아니면 더 정확한 접근 방법이 있습니까?

beforeEach(function() { 
    spyOn($http, 'post'); 
    spyOn($rootScope, '$broadcast').andCallThrough(); 
}); 

afterEach(function() { 
    $http.post.reset(); 
    $rootScope.$broadcast.reset(); 
}); 

it('should make a POST request to API endpoint', function() { 
    $http.post.andCallThrough(); 
    var response = { id: '123', role: 'employee', email: '[email protected]', username: 'someUsername' }; 
    $httpBackend.expectPOST(apiUrl + 'login').respond(response); 
    service.login(); 
    $httpBackend.flush(); 
    $timeout.flush(); 
    expect($rootScope.$broadcast.callCount).toBe(1); 
    expect($rootScope.$broadcast).toHaveBeenCalledWith(AUTH_EVENTS.loginSuccess, response); 
}); 
+1

'callCount'를 테스트하는 'expect'호출이 테스트의 첫 번째 줄로 이동되면,'callCount'는 그럼? 테스트에서 뭔가 다른 것이'$ broadcast'를 호출하는지 궁금합니다. –

답변

4

일이이 상황에서 작동하는 방법의 긴 조사, 마지막으로 테스트를 통과하고,이 솔루션은 현재 후 : 문제는 방송() 또는 reset 방법을 설정하라는 대해 아니었다

각 테스트 후 후 호출되지 않습니다 case를 andCallThrough()를 사용하는 동안. 문제는 $rootScope.$broadcast.andCallThrough();이 다른 이벤트에 의해 트리거되고 .callCount() 함수가 6을 반환한다는 것입니다. 이는 기본적으로 $broadcast 스파이가 6 번 호출되었음을 의미합니다.제 경우에는 AUTH_EVENTS.loginSuccess 이벤트에만 관심이 있으며 한 번만 방송되었는지 확인하십시오. 따라서 $rootScope.$broadcast.calls의 방법을 파고

expect($rootScope.$broadcast.callCount).toBe(1); 
expect($rootScope.$broadcast).toHaveBeenCalledWith(AUTH_EVENTS.loginSuccess, response); 

위의 두 가지 예상하는가 검색되어야하는 모든 통화의 내 배열을했다. 나는 질문의 첫 번째 부분 여기

재설정 방송()

을 종료

it('should make a POST request to API endpoint', function() { 
    $http.post.andCallThrough(); 
    var response = { id: '123', role: 'employee', email: '[email protected]', username: 'someUsername' }; 
    $httpBackend.expectPOST(apiUrl + 'login').respond(response); 
    service.login(); 
    $httpBackend.flush(); 
    $timeout.flush(); 

    var loginSuccessTriggerCount = _($rootScope.$broadcast.calls) 
    .chain() 
    .map(function getFirstArgument(call) { 
     return call.args[0]; 
    }) 
    .filter(function onlyLoginSuccess(eventName) { 
     return eventName === AUTH_EVENTS.loginSuccess; 
    }) 
    .value().length; 

    expect(loginSuccessTriggerCount).toBe(1); 
}); 
2

다른 접근법. 그것은 coffeescript 같은 의사 코드입니다. 일부 표현이 명확하지 않은 경우 의견에 질문하십시오. 질문에 대한 직접적인 대답이 아니라고 말해야합니다. 조금 다른 방법으로 비슷한 일을하는 방법에 불과합니다. 순수한 상태

시험은 방송을위한 스파이를 처리 할 변수를 소개하겠습니다. spyOn은 메소드 오버라이드 또는 믹싱을 처리 할 때 일부 성가신 경우에 좋지 않을 수 있기 때문에 나는 순수 스파이를 사용합니다.

rootScope$broadcastSpy = jasmine.createSpy() 

우리는 간첩과 자신의 상태를 처리하는 스텁으로 기원 구현을 교체해야합니다. 일반적인 스텁 정의에서는 자체 로직이없는 엔티티라고합니다. 그래서, 우리는 그것을 순수한 방식으로하고 여기에 어떤 논리도 두지 않습니다. 마커 (스파이로 표시).

beforeEach module ($provide) -> 
    $provide.value '$rootScope', 
    $broadcast: rootScope$broadcastSpy 

    return 

확실히, 우리는 스파이를 재설정해야 할 때 재스민과 이야기해야합니다.

beforeEach -> 
    rootScope$broadcastSpy.reset() 

은의 우리가 필요한 모든 서비스를 준비하고 컨텍스트 (즉 this)에 선언적인 방법으로 그들을 넣어 것입니다 테스트 범위를 정의 할 수 있습니다.

instance = (fnAsserts) -> 
    inject (loginService, $httpBackend, $timeout, apiUrl, AUTH_EVENTS) -> 
    fnAsserts.call 
     service: loginService 
     apiUrl: apiUrl 
     AUTH_EVENTS: AUTH_EVENTS 
     '$httpBackend': $httpBackend 
     '$timeout': $timeout 

테스트를 블랙 박스 방식으로 작성해 보겠습니다. 초기 상태를 설정하고 작업을 시작한 다음 마커에서 변경 사항을 확인합니다.


우리가 체인 인스턴스 defitions이 그들에게 더 많은 정보를 추가하고 우리가 한 곳에서 상태, 범위, 모의 객체 및 기타 필요한 물건을보기 때문에 순수한 방법으로 각 테스트를 작성할 수시피

it 'should make a POST request to API endpoint', instance -> 
    # Given 
    response = { id: '123', role: 'employee', email: '[email protected]', username: 'someUsername' } 
    @$httpBackend.expectPOST(@apiUrl + 'login').respond(response) 

    # When 
    @service.login() 

    # Then 
    @$httpBackend.flush() 
    @$timeout.flush() 
    expect(rootScope$broadcastSpy.callCount).toBe(1) 
    expect(rootScope$broadcastSpy).toHaveBeenCalledWith(@AUTH_EVENTS.loginSuccess, response) 
. 우리는 마커에 대해서만 클로저를 사용하고 부작용을 최소화합니다.

+0

CoffeeScript에 익숙하지 않으므로 @Gulin 응답에 감사드립니다.이 솔루션은 분명하지 않습니다. 특히, 'beforeEach module ($ provide) -> \ n $ provide.value'$ rootScope ', \ n $ broadcast : rootScope $ broadcastSpy \ n return''return'은 무엇을 반환합니까? – Max

+0

커피에서 모든 마지막 라인은 수익입니다. 하지만 여기에 명시 적으로 아무것도 반환하지 않는 반환을 배치했습니다. 'module' 구현은 반환 값을 사용하고 빈 반환을 통해'undefined'를 반환함으로써이 동작을 피합니다. –

0

이 나를 위해 작동합니다 : 결과적으로,이 솔루션은

$rootScope.$broadcast.calls.reset() 
관련 문제