Kaarotte
Kaarotte

Reputation: 31

Angular unit testing with ngMock - $timeout.flush() throws exception

I am using ngMock for unit testing and I need to use the $timeout.flush function in one of my tests, so I have added the two following lines to my test:

$timeout.flush();
$timeout.verifyNoPendingTasks();

as indicated on http://www.bradoncode.com/blog/2015/06/11/unit-testing-code-that-uses-timeout-angularjs/.

$timeout.flush() does flush the timeout as expected, however I am now getting an exception from angular-mocks.js every time I run my test:

LOG: 'Exception: ', Error{line: 1441, sourceURL: 'http://localhost:9876/base/node_modules/angular-mocks/angular-mocks.js?05a191adf8b7e3cfae1806d65efdbdb00a1742dd', stack: '$httpBackend@http://localhost:9876/base/node_modules/angular-mocks/angular-mocks.js?05a191adf8b7e3cfae1806d65efdbdb00a1742dd:1441:90 ....
global code@http://localhost:9876/context.html:336:28'}, 'Cause: ', undefined

Does anyone know where this exception could come from? I get it as many times as I use the $timeout.flush() function.

Looking at the angular-mocks.js file, it looks like it comes from the $httpBackend function. I have tried to update the ngMock version but it does not change anything. I have tried version 1.4.7 (which is my angular version) and version 1.6.2.

  function $httpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {

var xhr = new MockXhr(),
    expectation = expectations[0],
    wasExpected = false;

xhr.$$events = eventHandlers;
xhr.upload.$$events = uploadEventHandlers;

function prettyPrint(data) {
  return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
      ? data
      : angular.toJson(data);
}

function wrapResponse(wrapped) {
  if (!$browser && timeout) {
    if (timeout.then) {
      timeout.then(handleTimeout);
    } else {
      $timeout(handleTimeout, timeout);
    }
  }

  return handleResponse;

  function handleResponse() {
    var response = wrapped.response(method, url, data, headers, wrapped.params(url));
    xhr.$$respHeaders = response[2];
    callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
             copy(response[3] || ''));
  }

  function handleTimeout() {
    for (var i = 0, ii = responses.length; i < ii; i++) {
      if (responses[i] === handleResponse) {
        responses.splice(i, 1);
        callback(-1, undefined, '');
        break;
      }
    }
  }
}

if (expectation && expectation.match(method, url)) {
  if (!expectation.matchData(data)) {
    throw new Error('Expected ' + expectation + ' with different data\n' +
        'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT:      ' + data);
  }

  if (!expectation.matchHeaders(headers)) {
    throw new Error('Expected ' + expectation + ' with different headers\n' +
                    'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT:      ' +
                    prettyPrint(headers));
  }

  expectations.shift();

  if (expectation.response) {
    responses.push(wrapResponse(expectation));
    return;
  }
  wasExpected = true;
}

var i = -1, definition;
while ((definition = definitions[++i])) {
  if (definition.match(method, url, data, headers || {})) {
    if (definition.response) {
      // if $browser specified, we do auto flush all requests
      ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
    } else if (definition.passThrough) {
      originalHttpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers);
    } else throw new Error('No response defined !');
    return;
  }
}
throw wasExpected ?
    new Error('No response defined !') :
    new Error('Unexpected request: ' + method + ' ' + url + '\n' +
              (expectation ? 'Expected ' + expectation : 'No more request expected'));

}

Upvotes: 1

Views: 455

Answers (0)

Related Questions