Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

angular-mocks $httpBackend always return the same object instance when $http cache is enabled #13762

Open
@mjeanroy

Description

@mjeanroy

Suppose this function using $httpBackend :

$scope.find = function() {
  $http.get('/resource', { cache: true }).then(function(response) {
    var data = response.data;
    var parts = data.date.split('-').map(Number);
    data.date = Date.UTC(parts[0], parts[1] - 1, parts[0]);

    $scope.result = data;
  });
}

Note that:

  • We are using a cache.
  • We are transforming the response (here, we compute an UTC timestamp from a date formatted as 'yyyy-mm-dd').

Suppose this simple test :

it('should compute UTC date', function() {
    $httpBackend.whenGET('/resource').respond({
      date: '2016-01-01'
    });

    $scope.find();
    $httpBackend.flush();
    expect(angular.isNumber($scope.result.date)).toBe(true);

    // make a second call, it will fail
    $scope.find();
    $httpBackend.flush();
});

Here is the reason :

  • Response defined in the whenGET method is an object that will be returned by angular-mocks.
  • Since the http request is a cached request, this object will be put in the $http cache.
  • The success callback set the date as a timestamp on the object in the cache.
  • If I make a second call, the object in the cache is returned : the date attribute is now a number.

I can fix this in my test by using angular.toJson to specify that the response is not an object but a json string, but the problem could be solved in angular-mocks :

+ function _toJson(data) {
+   return angular.isObject(data) ? angular.toJson(data) : data;
+ }

function createResponse(status, data, headers, statusText) {
    if (angular.isFunction(status)) return status;

    return function() {
      return angular.isNumber(status)
-          ? [status, data, headers, statusText]
-          : [200, status, data, headers];
+          ? [status, _toJson(data), headers, statusText]
+          : [200, _toJson(status), data, headers];
    };

What do you think ? Should I fix this in my test or a PR is welcome ?

Note that this is a problem with angular-mocks, not with $http since the object stored in the $http cache is the server response (which is a string in a browser, deserialized in the defaultHttpResponseTransform function).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions