2014-11-05 3 views
8

저는 Angular의 $q Promise 구현을 사용하여 빌드 한 서비스를 테스트하려고합니다. 나는 약속대로 카르마, 모카, 차이, 시논, 시온 차이, 차이의 조합을 사용하고 있습니다.

내가 작성하고 약속을 되 돌리는 모든 테스트는 통과하지만 $q.all([ ... ])을 거부하거나 사용하는 테스트입니다. 내가 생각할 수있는 모든 것을 시도했지만 문제가 어디 있는지 찾을 수 없습니다.

가 다음 내가 테스트입니다 무엇의 슬림 버전 : 마지막

"use strict"; 


describe("Promise", function() { 

    var $rootScope, 
     $scope, 
     $q; 

    beforeEach(angular.mock.inject(function (_$rootScope_, _$q_) { 
     $rootScope = _$rootScope_; 
     $q = _$q_; 
     $scope = $rootScope.$new(); 
    })); 

    afterEach(function() { 
     $scope.$apply(); 
    }); 

    it("should resolve promise and eventually return", function() { 

     var defer = $q.defer(); 

     defer.resolve("incredible, this doesn't work at all"); 

     return defer.promise.should.eventually.deep.equal("incredible, this doesn't work at all"); 
    }); 

    it("should resolve promises as expected", function() { 

     var fst = $q.defer(), 
      snd = $q.defer(); 

     fst 
      .promise 
      .then(function (value) { 
       value.should.eql("phew, this works"); 
      }); 

     snd 
      .promise 
      .then(function (value) { 
       value.should.eql("wow, this works as well"); 
      }); 

     fst.resolve("phew, this works"); 
     snd.resolve("wow, this works as well"); 

     var all = $q.all([ 
      fst.promise, 
      snd.promise 
     ]); 

     return all.should.be.fullfiled; 
    }); 

    it("should reject promise and eventually return", function() { 
     return $q.reject("no way, this doesn't work either?").should.eventually.deep.equal("no way, this doesn't work either?"); 
    }); 

    it("should reject promises as expected", function() { 

     var promise = $q.reject("sadly I failed for some stupid reason"); 

     promise 
      ["catch"](function (reason) { 
       reason.should.eql("sadly I failed for some stupid reason"); 
      }); 

     var all = $q.all([ 
      promise 
     ]); 

     return all.should.be.rejected; 
    }); 

}); 

3 회, 그리고 첫 번째 테스트하는 것은 실패 할 것들입니다. 실제로 그것은 실패하지 않으며, 시간 초과가 초과되면 해결되고 Error: timeout of 2000ms exceeded이됩니다.

편집 : 나는 방금 Kris Kowal의 테스트 구현을 시도했지만 그걸로 잘 작동합니다.

P.나는 사실 Mocha, Chai 또는 Chai 약속의 그릇에 어딘가에 시간이 있다는 것을 발견했으며 걸이가 시간 초과보다 늦게 호출됩니다.

+0

의사 코드를 이해하고 있다면, 기대 한대로 텍스트를 입력 할 때까지'$ scope. $ apply()'를 호출하지 않은 것처럼 보입니다.약속을 해결하거나 거절 한 직후에 전화 해 볼 수 있습니까? –

+0

나는 실제로 그것을 시도해 보았습니다. 나는이 테스트를 통해 곧 도약 할 것입니다. – Roland

+0

'afterEach'에서'$ scope. $ apply()'를 실행하는 것은'afterEach'가 실행되기 전에 약속 값을 기대할 때 문제가 될 수 있습니다. –

답변

3

필자는 언뜻보기에는 테스트가 통과하지 않는 이유를 알아 내려고했습니다. 물론 나는 $scope.$apply();afterEach에서 @proloser로 언급 할 곳이 아니기 때문에 옮겨야 할 것입니다.

테스트를 완료했지만 테스트를 통과하지 못했습니다. 또한 chai-as-promisedangular에 관한 문제를 열어 의견/피드백을 받았는지 확인하고 실제로 작동하지 않을 가능성이 높다고 들었습니다. 그 이유는 아마도 Angular $q의 다이제스트 페이즈에 대한 의존성 때문일 것입니다. 다이제스트 페이즈는 chai-as-promsied 라이브러리에서 설명되지 않습니다.

따라서 Q 대신에 $q이라는 테스트를 확인 했으므로 정상적으로 작동하여 오류가 chai-as-promised 라이브러리에 없다는 내 가설을 강화했습니다.

나는 결국 차이가로서의 약속과 내가 대신 모카의 done 콜백을 사용하여 내 테스트를 다시 작성했습니다 하락했습니다 (뒤에서 약속 차이-AS-같은 않더라도) :

"use strict"; 


describe("Promise", function() { 

    var $rootScope, 
     $scope, 
     $q; 

    beforeEach(angular.mock.inject(function (_$rootScope_, _$q_) { 
     $rootScope = _$rootScope_; 
     $q = _$q_; 
     $scope = $rootScope.$new(); 
    })); 

    it("should resolve promise and eventually return", function (done) { 

     var defer = $q.defer(); 

     defer 
      .promise 
      .then(function (value) { 
       value.should.eql("incredible, this doesn't work at all"); 
       done(); 
      }); 

     defer.resolve("incredible, this doesn't work at all"); 

     $scope.$apply(); 

    }); 

    it("should resolve promises as expected", function (done) { 

     var fst = $q.defer(), 
      snd = $q.defer(); 

     fst 
      .promise 
      .then(function (value) { 
       value.should.eql("phew, this works"); 
      }); 

     snd 
      .promise 
      .then(function (value) { 
       value.should.eql("wow, this works as well"); 
      }); 

     fst.resolve("phew, this works"); 
     snd.resolve("wow, this works as well"); 

     var all = $q.all([ 
      fst.promise, 
      snd.promise 
     ]); 

     all 
      .then(function() { 
       done(); 
      }); 

     $scope.$apply(); 

    }); 

    it("should reject promise and eventually return", function (done) { 

     $q 
      .reject("no way, this doesn't work either?") 
      .catch(function (value) { 
       value.should.eql("no way, this doesn't work either?"); 
       done(); 
      }); 

     $scope.$apply(); 

    }); 

    it("should reject promises as expected", function (done) { 

     var promise = $q.reject("sadly I failed for some stupid reason"); 

     promise 
      ["catch"](function (reason) { 
       reason.should.eql("sadly I failed for some stupid reason"); 
      }); 

     var all = $q.all([ 
      promise 
     ]); 

     all 
      .catch(function() { 
       done(); 
      }); 

     $scope.$apply(); 

    }); 

}); 

위의 테스트는 모두 예상대로 진행됩니다. 다른 방법이있을 수 있지만 다른 방법을 알아낼 수 없으므로 다른 사람이 그렇다면 다른 사람들이 도움을 줄 수 있도록 게시하는 것이 좋을 것입니다.

+0

감사합니다 남자 u는 저에게 시간을 절약했다 – Blacksonic

+0

@blacksonic - 아무 문제도, 나는 고침을 찾아 낼 때까지 나 자신을 일 겪었다 : – Roland

13

afterEach()은 준비 후 테스트를 수행하기 전에 코드를 실행하지 않고 정리에 사용됩니다. $scope.$apply()도 정리가되지 않습니다.

는 다음과 같은 일을 할 필요가 : 당신의 검사 결과가 설정 및 평가 사이에하지에, 완료 후에는 $apply()을하고있는

// setup async behavior 
var all = $q.all(x.promise, y.promise) 

// resolve your deferreds/promises 
x.reject(); y.reject(); 

// call $scope.$apply() to 'digest' all the promises 
$scope.$apply(); 

// test the results 
return all.should.be.rejected; 

.

+0

원한다면이 [plnk] (http://plnkr.co/edit/IusDwx7ERoiqiUYKwqKn?p=preview)에서 테스트 해 볼 수 있습니다. 설정하는 데 어려움이 있습니다. 내 리소스 중 하나가 잘못되었거나 뭔가라고 생각합니다. 왜냐하면 콘솔에서 'beforeEach'가 누락되었다는 오류가 발생하기 때문입니다. 필자는 브라우저에서 테스트하려 한 적이 없기 때문에 실제로 작동하게하는 것이 도움이 될 것입니다. 따라서이 답변이 실제로 작동하는지 확인할 수 있고 다른 사용자가 볼 수 있도록 온라인 참조도 제공합니다. – Roland

+0

그 점은 제가 코멘트에 쓴 것입니다. 제가 그렇게 해본 적이 없기 때문에 브라우저에서 설정하는 것이 도움이 될 것입니다. 그리고 plnkr을 만들고 수정을 적용하여 실제로 원한다면 실제로 작동한다는 것을 보여줄 수 있습니다. 내 컴퓨터에서 로컬로 실행하고 작동한다고 말하면 다른 사용자가 동일한 문제에 걸려 넘어지지 않도록 도움을주지 않습니다. – Roland

+0

당신의 제안은 효과가 없으며 전에 제안한 것을 시도했습니다. 그래서 내가 브라우저에서 테스트를 설정하는 데 도움을 줄 수 있는지 물었고, 테스트를 통과했다면 다른 사용자들도 확인할 수 있습니다. – Roland

관련 문제