다이제스트를 강제할 $scope가 없는 경우 AngularJS, Jasmine 2.0에서 약속을 해결하는 방법은 무엇입니까?
-
21-12-2019 - |
문제
약속인 것 같다. 강제로 실행하지 않는 한 Angular/Jasmine 테스트에서 해결하지 마세요. $scope.$digest()
.이것은 어리석은 IMO이지만 괜찮습니다. 적용 가능한 곳(컨트롤러)에서 작동합니다.
지금 제가 처한 상황은 애플리케이션의 모든 범위에 대해 덜 신경 쓸 수 있는 서비스를 가지고 있다는 것입니다. 서비스는 서버에서 일부 데이터를 반환하지만 약속이 해결되지 않는 것 같습니다.
app.service('myService', function($q) {
return {
getSomething: function() {
var deferred = $q.defer();
deferred.resolve('test');
return deferred.promise;
}
}
});
describe('Method: getSomething', function() {
// In this case the expect()s are never executed
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
});
done();
});
// This throws an error because done() is never called.
// Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('should get something', function(done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
expect(1).toEqual(2);
done();
});
});
});
이 기능을 테스트하는 올바른 방법은 무엇입니까?
편집하다:참고용 솔루션입니다.분명히 서비스가 $rootScope를 사용하지 않더라도 $rootScope를 주입하고 소화해야 합니다.
it('should get something', function($rootScope, done) {
var promise = myService.getSomething();
promise.then(function(resp) {
expect(resp).toBe('test');
});
$rootScope.$digest();
done();
});
해결책
테스트에 $rootScope
를 주입하고 $digest
를 트리거해야합니다.
다른 팁
항상 $ RootScope가 있고,
를 사용합니다.inject(function($rootScope){
myRootScope=$rootScope;
})
....
myRootScope.$digest();
. 그래서 오후 내내 이것 때문에 고생했어요.이 게시물을 읽고 나 역시 답변에 뭔가 문제가 있다는 것을 느꼈습니다. 알고 보니 문제가 있었습니다.위의 답변 중 어느 것도 사용 위치와 이유에 대한 명확한 설명을 제공하지 않습니다. $rootScope.$digest
.그래서 여기 제가 생각해낸 것이 있습니다.
우선 왜?당신은 사용해야합니다 $rootScope.$digest
각도가 아닌 이벤트나 콜백에서 응답할 때마다.여기에는 순수 DOM 이벤트, jQuery 이벤트 및 기타 타사 Promise 라이브러리가 포함됩니다. $q
각도의 일부입니다.
두 번째로 어디?테스트가 아닌 코드에서.주사할 필요도 없고 $rootScope
테스트에서는 실제 각도 서비스에만 필요합니다.위의 모든 내용이 대답이 무엇인지 명확하게 밝히지 못하는 부분입니다. $rootScope.$digest
테스트에서 호출되는 것처럼.
이것이 동일한 문제를 겪고 있는 다음 사람에게 도움이 되기를 바랍니다.
업데이트
어제 이 게시물이 투표에서 거부되었을 때 삭제했습니다.오늘 나는 위에 친절하게 제공된 답변을 사용하려고 이 문제를 계속 겪었습니다.그래서 평판 포인트를 희생하고 답변을 대기하고 있으므로 삭제를 취소합니다.
이것은 각도가 아닌 이벤트 핸들러에 필요한 것이며 $q를 사용하고 Jasmine으로 테스트하려고 합니다.
something.on('ready', function(err) {
$rootScope.$apply(function(){deferred.resolve()});
});
어떤 경우에는 $timeout으로 래핑해야 할 수도 있습니다.
something.on('ready', function(err) {
$timeout(function(){
$rootScope.$apply(function(){deferred.resolve()});
});
});
메모 하나 더.당신이 전화하는 원래 문제 예에서
done
잘못된 시간에.전화를 하셔야 해요done
내부then
방법(또는catch
또는finally
), 약속의 해결 후입니다.Promise가 해결되기 전에 호출하고 있으며 이로 인해it
종료 조항.
각도 문서에서.
https://docs.angularjs.org/api/g/service/ks.org/api/g/service/k> $ q
it('should simulate promise', inject(function($q, $rootScope) {
var deferred = $q.defer();
var promise = deferred.promise;
var resolvedValue;
promise.then(function(value) { resolvedValue = value; });
expect(resolvedValue).toBeUndefined();
// Simulate resolving of promise
deferred.resolve(123);
// Note that the 'then' function does not get called synchronously.
// This is because we want the promise API to always be async, whether or not
// it got called synchronously or asynchronously.
expect(resolvedValue).toBeUndefined();
// Propagate promise resolution to 'then' functions using $apply().
$rootScope.$apply();
expect(resolvedValue).toEqual(123);
}));
.