Angular 1 / ui-select / Jasmine - 测试元素(如果存在于ng-if中)

时间:2017-07-27 09:02:36

标签: angularjs jasmine karma-jasmine ui-select

我想测试ng-if内是否存在输入,如果测试完全通过而不是ng-if,则不使用ng。

在我的模板中,我有:

  <div ng-if="$ctrl.doShowAir">
    <input class="form-control" type="text">
  </div>

doShowAir是函数doShow()中的变量,在以前的ui-select中选择一个选项时应该是true

  <ui-select ng-model="$ctrl.parking.parkingType"
             on-select="$ctrl.doShow()">
    <ui-select-match>
      <span>{{ $select.selected.label }}</span>
    </ui-select-match>
    <ui-select-choices repeat="item in $ctrl.projectReferences.parkingType | filter: { label: $select.search }">
      <span ng-bind-html="item.label"></span>
    </ui-select-choices>
  </ui-select>

功能:

  doShow() {
    this.doShowAir = (this.parkingType.labelKey === 'parking_type.air')
  }

单元测试:

import angular from 'angular'
import 'angular-mocks'

let scope
let rootScope
let compile
let htmlElement
let ctrl

fdescribe('projectExteriorParking', () => {
  beforeEach(() => {
    angular.mock.module('ProjectExteriorParkingModule')
    angular.mock.module('ui.select')
  })

  beforeEach(inject((_$compile_, _$rootScope_) => {
    rootScope = _$rootScope_
    compile = _$compile_
    scope = rootScope.$new()
    scope.parking = {}
    htmlElement = compile(`<project-exterior-parking parking="project.realEstateProjectProduct.parkings"></project-exterior-parking>`)(scope)
    rootScope.$digest()
  }))

  beforeEach(inject(($componentController) => {
    let bindings = {
      parking: {},
      projectReferences: {}
    }
    ctrl = $componentController('projectExteriorParkingModule', null, bindings)
  }))

  it('should contain two input', () => {
    const inputItems = htmlElement.get(0).querySelectorAll('input')
    expect(inputItems.length).toBe(2)
  })
})

如何模拟变量shouldShowAir为真,或模拟调用函数的ui-select上的选择on-select="$ctrl.doShow()"因为我无法访问doShow()函数。 或者如何“手动”将输入添加到测试中并在<project-exterior-parking parking="project.realEstateProjectProduct.parkings"></project-exterior-parking>

之外编译它

1 个答案:

答案 0 :(得分:0)

要获取编译元素的控制器,请调用ctrl = htmlElement.controller('directive|component name')

在您的情况下ctrl = htmlElement.controller('projectExteriorParking')

directive|component是您向angular.module注册组件或指令时提供的字符串

知道如何从已编译的htmlElement中获取控制器,现在可以调用ctrl.doShow()$rootScope.$apply(),然后断言元素的呈现方式与测试中的方式相同

您的代码中还有其他一些内容: ng-model="$ctrl.parking.parkingType"

doShow() {
  // ngModel is this.parking.parkingType
  // is there this.parkingType or is this a mistake?
  this.doShowAir = (this.parkingType.labelKey ===  'parking_type.air')
}

传递给$ compile的范围缺少require绑定:

beforeEach(inject((_$compile_, _$rootScope_) => {
  rootScope = _$rootScope_
  compile = _$compile_
  scope = rootScope.$new()
  scope.parking = {}
  // The compiled element has `parking` bound to `project.realEstate...` yet you don't have it on scope
 // you should assign some mock data as `scope.project = { realEstateProjectProduct }`
  htmlElement = compile(`<project-exterior-parking parking="project.realEstateProjectProduct.parkings"></project-exterior-parking>`)(scope)
  rootScope.$digest()

}))

您应该传递一些模拟数据,或者将ctrl.parkingType设置为期望会使方法ctrl.doShow()设置为ctrl.doShowAir为真的值