简体   繁体   中英

AngularJS 1.5 unit testing UI-Router state changes within controller

I have a AngularJS 1.5 app in which I use the UI-Router. The problem I'm having is with unit testing my state changes within the controller.

I have the following logic in my controller

CostingsController = ($scope, $http, $state, flash) ->

  if $state.current.name == "costing_new"
    if $scope.current_division
      $http.get('/costings/new').then ((response) ->
        $scope.costing = response.data
      )
    else
      flash("alert", "Please select a division", 2000)
      $state.go "divisions"

I'm trying to test that the state changes to divisions when there is no division selected. This code works in practice but not in the tests. Here is my Jasmine test

  describe "when division is not selected", ->
    beforeEach(inject ( ($controller, $rootScope, $location, $state, $httpBackend) ->
      @state = $state
      @redirect = spyOn(@state, 'go')
      @state.transitionTo('costing_new')

      ctrl = $controller('CostingsController', {
        $scope: @scope,
        $location: $location,
        $state: @state
      })
    ))

    it "redirects to division", ->
      expect(@state.go).toHaveBeenCalledWith('divisions')

The error I get is;

Chrome 63.0.3239 (Linux 0.0.0) CostingsController Controller: costings_controller new when division is not selected redirects to division FAILED
    Expected spy go to have been called with [ 'divisions' ] but it was never called.
        at Object.<anonymous> (/home/map7/code/pais/spec/javascripts/unit/costing_controller_spec.js.js:47:40)
Chrome 63.0.3239 (Linux 0.0.0): Executed 1 of 394 (1 FAILED) (skipped 393) ERROR (0.403 secs / 0.197 secs)

Update: using angular.copy

  describe "when division is not selected", ->
        beforeEach(inject ( ($controller, $rootScope, $location, $state, $httpBackend) ->
          @state = angular.copy({current: {name: 'costing_new'}}, $state)
          @redirect = spyOn(@state, 'go')

          ctrl = $controller('CostingsController', {
            $scope: @scope,
            $location: $location,
            $state: @state
          })
        ))

        it "redirects to division", ->
          expect(@state.go).toHaveBeenCalledWith('divisions')

If I use the above with angular.copy I get the following error;

TypeError: Cannot set property current of #<StateService> which has only a getter

Taking estus help I've mocked state like so

  describe "when division is not selected", ->
    beforeEach(inject ( ($controller, $state) ->
      @state = {
        current: {name: "costing_new"},
        go: jasmine.createSpy("go")
      }

      ctrl = $controller('CostingsController', {
        $scope: @scope,
        $state: @state
      })
    ))

    fit "redirects to division", ->
      expect(@state.go).toHaveBeenCalledWith('divisions')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM