Jasmine 2.0을 사용한 비동기 테스트에서 "$digest aready progress"가 표시됨
나는 그 소명을 안다.$digest또는$apply다이제스트 사이클 중에 수동으로 "$digest already in progress" 오류가 발생하지만 왜 여기서 이 오류가 발생하는지 알 수 없습니다.
이것은 서비스 유닛테스트입니다.$http서비스는 충분히 심플합니다.콜을 실행하려고 하는 코드가 예기한 데이터를 계속 얻을 수 있도록 하면서 서버에 대한 중복 콜을 회피할 뿐입니다.
angular.module('services')
.factory('httpService', ['$http', function($http) {
var pendingCalls = {};
var createKey = function(url, data, method) {
return method + url + JSON.stringify(data);
};
var send = function(url, data, method) {
var key = createKey(url, data, method);
if (pendingCalls[key]) {
return pendingCalls[key];
}
var promise = $http({
method: method,
url: url,
data: data
});
pendingCalls[key] = promise;
promise.then(function() {
delete pendingCalls[key];
});
return promise;
};
return {
post: function(url, data) {
return send(url, data, 'POST');
},
get: function(url, data) {
return send(url, data, 'GET');
},
_delete: function(url, data) {
return send(url, data, 'DELETE');
}
};
}]);
유닛 테스트도 매우 간단합니다.$httpBackend요구를 상정합니다.
it('does GET requests', function(done) {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
done();
});
$httpBackend.flush();
});
이것은 와 같이 폭발한다.done()"$syslog aready in progress" 오류와 함께 호출됩니다.왜 그랬는지 모르겠어.나는 이것을 포장해서 해결할 수 있다.done()이런 타임아웃에
setTimeout(function() { done() }, 1);
즉,done()$digest가 완료된 후 큐잉되어 실행되지만 문제가 해결되는 동안 알고 싶습니다.
- 애초에 Angular가 다이제스트 사이클에 있는 이유는 무엇입니까?
- 콜은 왜?
done()이 오류를 트리거하시겠습니까?
Jasmine 1.3에서도 동일한 테스트를 Green으로 실행했는데, 이는 Jasmine 2.0으로 업그레이드하고 새로운 비동기 구문 분석을 사용하기 위해 테스트를 다시 작성한 후에만 발생합니다.
$httpBacked.flush()를 실제로 기동하여 완료$digest()어제 하루종일 ngResource와 angular-mocks의 출처를 조사했는데도 아직 완전히 이해하지 못했습니다.
내가 알기로는 의 목적은$httpBackend.flush()위의 비동기 구조를 완전히 회피하는 것입니다.즉, 의 구문은it('should do something',function(done){});그리고.$httpBackend.flush()사이가 좋지 않다의 바로 그 목적.flush()보류 중인 비동기 콜백을 푸시하고 되돌리는 것입니다.마치 큰 것 같다done모든 비동기 콜백을 랩핑합니다.
따라서 올바르게 이해하고 있는 경우(그리고 현재 기능하고 있는 경우) 올바른 방법은 이 명령어를 삭제하는 것입니다.done()프로세서(사용 시)$httpBackend.flush():
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
});
$httpBackend.flush();
});
console.log 문을 추가하면 모든 콜백이 다음 중 일관되게 발생합니다.flush()사이클:
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
console.log("pre-get");
service.get('/some/random/url').then(function(result) {
console.log("async callback begin");
expect(result.data).toEqual('The response');
console.log("async callback end");
});
console.log("pre-flush");
$httpBackend.flush();
console.log("post-flush");
});
다음으로 출력은 다음과 같습니다.
프리겟
사전 준비
비동기 콜백 시작
비동기 콜백엔드
사후 처리
매번.정말 보고 싶다면 스코프를 잡고scope.$$phase
var scope;
beforeEach(function(){
inject(function($rootScope){
scope = $rootScope;
});
});
it('does GET requests', function() {
$httpBackend.expectGET('/some/random/url').respond('The response');
console.log("pre-get "+scope.$$phase);
service.get('/some/random/url').then(function(result) {
console.log("async callback begin "+scope.$$phase);
expect(result.data).toEqual('The response');
console.log("async callback end "+scope.$$phase);
});
console.log("pre-flush "+scope.$$phase);
$httpBackend.flush();
console.log("post-flush "+scope.$$phase);
});
출력은 다음과 같습니다.
사전 정의되지 않음
사전 정의가 정의되지 않음
비동기 콜백 시작 $syslog
비동기 콜백 종료 $syslog
정의되어 있지 않다
@ 그 @deitch가 맞다.$httpBacked.flush()다이제스트를 트리거합니다.는 이 입니다.$httpBackend.verifyNoOutstandingExpectation(); 뒤에 .it완성되면 다이제스트도 있습니다.하다
- 은 ""라고 부른다"
flush(). then()done()verifyNoOutstandingExpectation()다이제스트를 트리거하는 실행입니다만, 이미 다이제스트에 들어가 있기 때문에 에러가 발생합니다.
done()까지는 '아'가한데, ''아'가 있어야 입니다.then()실행까지 됩니다. 경우,then실행되지 않으면 장애가 발생했음을 알 수 있습니다.가 잘 입니다.done().
it('does GET requests', function(done) {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
setTimeout(done, 0); // run the done() after the current $digest is complete.
});
$httpBackend.flush();
});
「 」를 .done()타임아웃 시 현재 다이제스트가 완료된 후 즉시 실행됩니다., 「」의 됩니다.expects도망가고 싶었던 게 실제로 도망가는 거야
@deitch의 답변에 추가.테스트를 보다 견고하게 하기 위해 콜백 전에 스파이를 추가할 수 있습니다.이것에 의해, 콜백이 실제로 콜 되는 것이 보증됩니다.
it('does GET requests', function() {
var callback = jasmine.createSpy().and.callFake(function(result) {
expect(result.data).toEqual('The response');
});
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(callback);
$httpBackend.flush();
expect(callback).toHaveBeenCalled();
});
언급URL : https://stackoverflow.com/questions/24341544/getting-digest-already-in-progress-in-async-test-with-jasmine-2-0
'source' 카테고리의 다른 글
| Wordpress API Post에 META 필드를 포함하려면 어떻게 해야 합니까? (0) | 2023.03.04 |
|---|---|
| react.js는 jQuery/UI 컴포넌트와 잘 어울린다 (0) | 2023.03.04 |
| wordpress fishpig magento 설치 - getPostListHtml() (0) | 2023.03.04 |
| Postgres의 json 개체에서 키, 값 추출 (0) | 2023.03.04 |
| 배열의 각도 변화를 관찰하는 방법JS (0) | 2023.03.04 |