Last Updated: February 25, 2016
·
1.655K
· brunochauvet

Stub multiple promises with AngularJS and SinonJS

When testing your AngularJS application, you surely want to stub your back-end REST interface. I was facing a problem where I needed to load different objects from the same API endpoint but returning different values. Luckily, SinonJS provides support for returning multiple responses.

Our application model

myApp.factory 'Model', [ '$http', ($http) ->
  http_promises = []
  Model = {}
  Model.find = (id) ->
    if not http_promises[id]?
      http_promises[id] = $http.get("model/#{id}").then (response) -> response.data
    http_promises[id]

  Model
]

And Controller

myApp.controller 'ModelController', [ '$scope', 'Model', ($scope, Model) ->
  $scope.model1 = Model.find(1)
  $scope.model2 = Model.find(2)
...
]

And to test sequential calls in our unit tests, we stub the multiple promises:

beforeEach inject(($rootScope, $controller, Model) ->
      scope = $rootScope.$new()

      model1 = {id: 1}
      model2 = {id: 2}

     model1_promise = {
        then: (callback) -> callback(model1)
      }

      model2_promise = {
        then: (callback) -> callback(model2)
      }

      sinon.stub(Model, 'find')
        .onFirstCall().returns(model1_promise)
        .onSecondCall().returns(model2_promise)

it 'attaches the model1 to the scope', ->
      expect(scope.model1).toBe model1
      expect(scope.model2).toBe model2