jeudi 25 février 2016

How to spyOn chained function calls for unit testing (with angular, jasmine and sinon)

My example is using the alchemy.js library but it can be more

My controller has this method:

$scope.getNodes = function() {
  return $scope.alchemy.get.nodes().all();
};

The unit test:

describe('$scope.getNodes', function () {
  beforeEach(function() {
    $rootScope.alchemy = sinon.stub({
      get: function() {}
    });
    $rootScope.alchemy.get = sinon.stub({
      nodes: function() {}
    });
    $rootScope.alchemy.get.nodes = sinon.stub({
      all: function() {}
    });
    spyOn($rootScope.alchemy, 'get').and.returnValue($rootScope.alchemy.get.nodes);
    spyOn($rootScope.alchemy.get, 'nodes').and.returnValue($rootScope.alchemy.get.nodes.all);
    spyOn($rootScope.alchemy.get.nodes, 'all').and.returnValue(["node1", "node2"]);
  });

  it('should call $scope.alchemy.get.nodes().all()', function() {
    $rootScope.getNodes();
  });
});

The error produced is:

TypeError: undefined is not a function (evaluating '$scope.alchemy.get.nodes().all()') in /path/to/controllers/Controller.js (line 43)

Now, the test will pass if I change the controller code to omit the brackets on the nodes method:

return $scope.alchemy.get.nodes.all();

If anyone has a better suggestion to how I actually mock the functions better with sinon I'd appreciate it (I don't think my method is the most optimal).

Also, is "chaining" the correct term for multiple.method.calls.like.this?

Aucun commentaire:

Enregistrer un commentaire