programing

단위 테스트 약속 기반 코드(Angularjs)

instargram 2023. 4. 2. 09:44
반응형

단위 테스트 약속 기반 코드(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; } };
};

또 하나의 옵션으로서 전화할 필요가 없습니다.$digestQ 라이브러리(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

반응형