programing

약속을 돌려주는 유닛 테스트 서비스 Angularjs Jasmine

abcjava 2023. 3. 27. 20:51
반응형

약속을 돌려주는 유닛 테스트 서비스 Angularjs Jasmine

Michal Charemza 투고에 따라 편집되었습니다.

angului 모달 대화 상자를 나타내는 서비스가 있습니다.

app.factory("dialogFactory", function($modal, $window, $q) {

    function confirmDeleteDialog() {

    var modalInstance = $modal.open({
        templateUrl: "../application/factories/confirmDeleteDialog.htm",
        controller: function($scope, $modalInstance) {

            $scope.ok = function() {
                $modalInstance.close("true");
            };

            $scope.cancel = function() {
                $modalInstance.dismiss("false");
            };
        }
    });


    return modalInstance.result.then(function(response) {
        return 'My other success result';
    }, function(response) {
        return $q.reject('My other failure reason');
    });

};

    return {
        confirmDeleteDialog: confirmDeleteDialog
    };

});

사용자가 대화상자에서 [확인]을 클릭한 경우 삭제 메서드를 호출할 때requestNotificationChannel.deleteMessage(id)실행됩니다.

$scope.deleteMessage = function(id) {
        var result = dialogFactory.confirmDeleteDialog();

        result.then(function(response) {
            requestNotificationChannel.deleteMessage(id);
        });
    };

문제는 유닛 테스트를 할 수 없다는 것입니다.

이건 내 시험이야.Q 서비스를 올바르게 삽입했지만 무엇을 반환해야 할지 모르겠습니다."confirmDeleteDialog"스파이...

describe("has a delete method that should call delete message notification", function() {
            var deferred = $q.defer();
            spyOn(dialogFactory, "confirmDeleteDialog").and.returnValue(deferred.promise);

            spyOn(requestNotificationChannel, "deleteMessage");

            $scope.deleteMessage(5);
            deferred.resolve();

            it("delete message notification is called", function() {
                expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
            });
        });

하지만 나는 받고 있다.expected spy deleteMessage to have been called그 말은 즉,result.then... 부품이 실행되지 않습니다.제가 무엇을 빠뜨리고 있나요?

약속을 반환하는 함수를 조롱하려면 약속도 반환해야 하며, 그 후 별도의 단계로 해결되어야 합니다.

고객님의 경우deferred.resolve()스파이에게 패스하는 경우는, 다음과 같이 대체해야 합니다.deferred.promise및 deferred.delected()는 개별적으로 실행됩니다.

beforeEach(function() {
  var deferred = $q.defer();
  spyOn(dialogFactory, "confirmDeleteDialog").and.returnValue(deferred.promise);
  spyOn(requestNotificationChannel, "deleteMessage");
  $scope.deleteMessage(5);
  deferred.resolve();
  $rootScope.$digest();
});

it("delete message notification is called", function() {
  expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
});

내 생각엔 너도 전화해야 할 것 같아$rootScope.$digest()Angular의 약속 구현은 다이제스트 루프와 관련되어 있습니다.

또, 질문과는 약간 관련이 없지만, 독자적인 지연 오브젝트를 작성할 필요는 없다고 생각합니다.confirmDeleteDialog사용하고 있는 (안티) 패턴에는 http://taoofcode.net/promise-anti-patterns/과 같이 '잊혀진 약속'이라는 라벨이 붙어 있습니다.

보다 심플하고, 코드 사용이 적고, 그것이 에러 처리를 향상시킨다고 생각합니다만, 그 약속을 되돌리면 됩니다.$modal서비스는 다음을 작성합니다.

var modalInstance = $modal.open({...});
return modalInstance.result;

콜링 함수에 표시되는 값을 해결된 값 또는 거부된 값으로 변경하는 경우 다음 결과를 반환함으로써 체인된 약속을 작성할 수 있습니다.then:

var modalInstance = $modal.open({...});
return modalInstance.result.then(function(successResult) {
  return 'My other success result';
}, function(failureReason) {
  return $q.reject('My other failure reason');
});

일반적으로 함수의 내부 기능을 호출자에게 노출하지 않을 경우 이 작업을 수행할 수 있습니다.이는 동기 프로그래밍에서 예외를 재투입하는 개념과 유사합니다.

언급URL : https://stackoverflow.com/questions/22905581/unit-test-service-that-returns-promise-angularjs-jasmine

반응형