【问题标题】:AngularJS 1.5 unit testing UI-Router state changes within controllerAngularJS 1.5 单元测试控制器内的 UI-Router 状态更改
【发布时间】:2018-07-22 04:15:51
【问题描述】:

我有一个使用 UI-Router 的 AngularJS 1.5 应用程序。我遇到的问题是在控制器中对我的状态更改进行单元测试。

我的控制器中有以下逻辑

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"

我正在尝试测试当没有选择分区时状态是否更改为分区。此代码在实践中有效,但在测试中无效。这是我的茉莉花测试

  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')

我得到的错误是;

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)

更新:使用 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')

如果我将上述内容与 angular.copy 一起使用,则会出现以下错误;

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

【问题讨论】:

  • 请务必说明问题使用的是 Coffeescript,因为大多数 Angular(JS) 开发人员不习惯这种术语。您正在使用flash 之类的东西,并且它没有被存根 - 而除了您正在测试的单元(控制器)之外的所有东西都应该是。我猜它通过调用警报来暂停脚本,不是吗?
  • flash 只是一个 toast 消息,它不会暂停执行。
  • 出于同样的原因考虑模拟整个 $state 服务,因为它破坏了测试隔离并使其依赖于第三方单元。这很可能是这里发生的事情。该测试依赖于 state.transitionTo 行为,但它不一定会像您期望的那样运行(它可能需要 $rootScope.$digest() 或其他)。见stackoverflow.com/questions/35899581/…

标签: angularjs unit-testing coffeescript angular-ui-router jasmine


【解决方案1】:

在 estus 的帮助下,我已经像这样嘲笑国家了

  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')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    相关资源
    最近更新 更多