Program Tip

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

programtip 2020. 11. 11. 20:32
반응형

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합니다. 그것은 모두 매우 지루하고 많은 상용구 코드입니다.

그런 것들을 테스트하는 다른 방법이 있습니까? 아니면 내 디자인 냄새가 나나요?


여전히 서비스를 모의하고 promise를 반환해야하지만 대신 실제 promise를 사용해야하므로 해당 기능을 구현할 필요가 없습니다. 사용은 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; } };
};

And as yet another option you can avoid having to call $digestby using the Q library (https://github.com/kriskowal/q) as a drop-in replacement for $q e.g:

beforeEach(function () {
    module('Module', function ($provide) {
        $provide.value('$q', Q); 
    });
});

This way promises can be resolved/rejected outside of the $digest cycle.

참고URL : https://stackoverflow.com/questions/16081586/unit-test-promise-based-code-in-angularjs

반응형