단위 테스트 약속 기반 코드(Angularjs)
Angularjs에서 약속 기반 코드를 테스트하는 데 어려움을 겪고 있습니다.
컨트롤러에 다음 코드가 있습니다.
$scope.markAsDone = function(taskId) {
tasksService.removeAndGetNext(taskId).then(function(nextTask) {
goTo(nextTask);
})
};
function goTo(nextTask) {
$location.path(...);
}
다음 사례를 유닛 테스트하고 싶습니다.
- 언제
markAsDone
라고 불리고 있습니다.tasksService.removeAndGetNext
- 언제
tasksService.removeAndGetNext
로케이션을 변경할 필요가 있습니다(개요).goTo
)
제가 보기엔 그 두 사건을 따로따로 검사하는 것은 쉬운 방법이 아닌 것 같습니다.
첫 번째 테스트를 위해 한 것은 다음과 같습니다.
var noopPromise= {then: function() {}}
spyOn(tasksService, 'removeAndGetNext').andReturn(noopPromise);
이제 두 번째 사건을 테스트하기 위해 항상 그럴만한 가짜 약속을 하나 더 만들어야겠어resolved
꽤 지루하고 많은 상용 코드입니다.
그런 것들을 테스트할 수 있는 다른 방법이 있나요?아니면 제 디자인에서 냄새가 나요?
서비스를 비웃고 약속을 되돌려야 하지만, 그 대신 실제 약속을 사용해야 하므로 그 기능을 구현할 필요가 없습니다.사용하다beforeEach
항상 해결이 필요한 경우 이미 이행된 약속을 만들고 서비스를 조롱합니다.
var $rootScope;
beforeEach(inject(function(_$rootScope_, $q) {
$rootScope = _$rootScope_;
var deferred = $q.defer();
deferred.resolve('somevalue'); // always resolved, you can do it from your spec
// jasmine 2.0
spyOn(tasksService, 'removeAndGetNext').and.returnValue(deferred.promise);
// jasmine 1.3
//spyOn(tasksService, 'removeAndGetNext').andReturn(deferred.promise);
}));
각각의 문제를 해결하려면it
지연된 값을 다른 값으로 블록한 다음 지연된 로컬 변수를 노출하고 사양에서 해결하면 됩니다.
물론 테스트를 그대로 유지할 수 있지만, 여기 작동 방식을 보여 주는 매우 간단한 사양이 있습니다.
it ('should test receive the fulfilled promise', function() {
var result;
tasksService.removeAndGetNext().then(function(returnFromPromise) {
result = returnFromPromise;
});
$rootScope.$apply(); // promises are resolved/dispatched only on next $digest cycle
expect(result).toBe('somevalue');
});
테스트하고 있던 컨트롤러에서 바로 꺼낸 다음 접근법이 있습니다.
var create_mock_promise_resolves = function (data) {
return { then: function (resolve) { return resolve(data); };
};
var create_mock_promise_rejects = function (data) {
return { then: function (resolve, reject) { if (typeof reject === 'function') { return resolve(data); } };
};
var create_noop_promise = function (data) {
return { then: function () { return this; } };
};
또 하나의 옵션으로서 전화할 필요가 없습니다.$digest
Q 라이브러리(https://github.com/kriskowal/q)를 드롭인 대체 수단으로 사용하여$q
예:
beforeEach(function () {
module('Module', function ($provide) {
$provide.value('$q', Q);
});
});
이렇게 하면 $digest 사이클을 벗어나 약속을 해결/거부할 수 있습니다.
언급URL : https://stackoverflow.com/questions/16081586/unit-test-promise-based-code-in-angularjs
'programing' 카테고리의 다른 글
SQL Output 절에서 삽입되지 않은 열을 반환할 수 있습니까? (0) | 2023.04.07 |
---|---|
시간을 클리어 또는 정지하는 방법angularjs 간격? (0) | 2023.04.02 |
FormController에서 양식 제어 가져오기 (0) | 2023.04.02 |
[ Gson Serialize ]필드는 늘이 아니거나 공백이 아닌 경우에만 (0) | 2023.04.02 |
Wordpress 역할 표시 이름 (0) | 2023.04.02 |