Test method of an AngularJs controller with promise using Karma, Mocha, Chai, Sinon

1

I'm not able to test the code that runs on then of promise

I have the following controller:

class Product extends Controller
  constructor: ($scope, productService) ->
    $scope.product = productService.new()
    $scope.products = []

    $scope.create = ->
      productService.create($scope.product).$promise.then (res) ->
        $scope.products.unshift(res)
        $scope.product = productService.new()

And the following test class:

describe 'productsController', ->
  q = scope = controller = productService = productServiceMock = undefined

beforeEach module('e-city')

beforeEach ->
  productServiceMock =
    new: -> a: 'a'
    create: (p)->
      qq = q.defer()
      qq.resolve(p)
      $promise: qq.promise
  module ($provide) ->
    $provide.value 'productService', productServiceMock
    null

beforeEach ->
  inject (_productService_, $controller, $rootScope, $q) ->
    q = $q
    productService = _productService_
    scope = $rootScope.$new()
    controller = $controller 'productController', $scope: scope

describe 'should test the create method', ->
  it 'should set a new object on $scope.product',  ->
    spy = sinon.spy productService, 'create'
    scope.create()
    spy.should.have.been.called

In my test I created a Mock for the productService to run the tests without bothering the bank. The Mock issue is working correctly, I just can not test if productService.new () is being called when the promise of the productService .create ($ scope.product) is resolved. What could it be?

    
asked by anonymous 11.06.2015 / 21:33

1 answer

0

For this problem reported above in specific the code below already solves the problem.

describe 'create', ->
  it 'should call "new"', inject ($timeout)->
    spy = sinon.spy productService, 'new'
    scope.create()
    $timeout.flush()
    spy.should.have.been.called
    productService.new.restore()
  

Note: To optimize the tests and make mocks easier to use, it is recommended to use the $ httpBackend of AngularJs .

    
11.06.2015 / 22:59