0

I'm trying to test what the following method returns in it's promise (functionToTest and asyncGet are both methods defined in an angularJS service):

var functionToTest = function (param) {
  var deferred = $q.defer();

  asyncGet(param).then(function (result) {
    //business login involving result

    if (something) 
      return deferred.resolve(true);
    else
      return deferred.resolve(false);
  });

  return deferred.promise;
}

The unit test looks like this:

it ('should return true', function (done) {
  var asyncGetResult = {};
  spyOn(asyncGet).and.returnValue($q.resolve(asyncGetResult));  

  var param = {};
  functionToTest(param).then(function (result) {
     expect(result).toBe(true);
     done();
  }); 

  $scope.$apply();
});

When running the test I am getting a timeout error:

Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

I tried putting a console.log() right after the expect() but it does not print anything, so it seems like the callback for the functionToTest(param).then() is never executed.

Any help would be appreciated.

georgeawg
  • 48,608
  • 13
  • 72
  • 95

1 Answers1

0

Remove the $q.deferred anti-pattern:

var functionToTest = function (param) {

  ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶

  return asyncGet(param).then(function (result) {
    //business login involving result

    if (something) 
      return true;
    else
      return false;
  });

  ̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶

}

Also provide an error handler:

  functionToTest(param).then(function (result) {
     expect(result).toBe(true);
     done();
  }).catch(function(err) {
     console.log(err);
     done();
  });

Deferred anti-patterns can hang if the code is written erroneously. Avoid the anti-pattern to prevent this problem.

Include a .catch handler to see any errors.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Thank you for the suggestion! I removed the anti pattern from my code, but unfortunately the test still gives a timeout. The catch() error handler is also not triggered. – Gellért Kovács Nov 29 '19 at 07:42