如何在Jasmine/Angularjs中单元测试下拉列表

8
我正在尝试单元测试一个指令,该指令使用一些JSON来指定列表的详细信息以创建下拉列表。该指令运行正常,但我在尝试单元测试时遇到了问题。
以下是测试:
/* global inject, expect, angular */

define(function(require){
  'use strict';
  require('angular');
  require('angularMock');
  require('reporting/js/directives/app.directives');
  require('reporting/js/directives/drop.down.field.directive');

  describe("drop down field", function() {
    // debugger;
    var directive, scope;
    beforeEach(module('app.directives'));
    beforeEach(inject(function($compile, $rootScope) {
      scope = $rootScope;

      scope.dropDownResponses = {};
      scope.dropDownField = {
        "name": "Test Drop Down",
        "type": "dropdown",
        "hidden": "false",
        "defaultValue": "None",
        "values": [
          {
            "key": "1",
            "value": "FL",
            "select": "true"
          },
          {
            "key": "2",
            "value": "GA",
            "select": "false"
          },
          {
            "key": "3",
            "value": "TX",
            "select": "false"
          }
        ],
        "validation": null
      };
      directive = angular.element('<div drop-down-field="dropDownField" drop-down-responses="dropDownResponses"></div>');
      $compile(directive)(scope);
      scope.$digest();
    }));
    it("should build three dropdown choices", function() {
      expect(directive.find('option').length).toBe(4);
    });
    it('should have one dropdown', function() {
      expect(directive.find("select").length).toBe(1);
    });
    it('should update the model when a new choice is selected', function() {
      angular.element(directive.find("select")[0]).val('1');
      angular.element(directive.find("select")[0]).change();
      expect(scope.dropDownResponses[scope.dropDownField.name]).toBe("1");
    });
  });
});

这是指令:
define(function(require) {
  'use strict';

  var module = require('reporting/js/directives/app.directives');
  var template = require('text!reporting/templates/drop.down.field.tpl');

  module.directive('dropDownField', function () {
    return {
      restrict: 'A',
      replace: true,
      template:template,
      scope: {
        dropDownField : "=",
        dropDownResponses : "="
      }
    };
  });

  return module;
});

这是标记语言的代码:
<div>
  {{dropDownField.name}}
  <select ng-model="dropDownResponses[dropDownField.name]" ng-options="value.key as value.value for value in dropDownField.values"></select>
</div>

最后一个代码块是我们关注的重点。当我触发更改事件时,模型中的值总是比预期多一个。例如,在这种情况下存储在scope.dropDownResponses中的值最终变为2。
有什么想法吗?

没有看到实际指令,真的很难提供帮助。 - Jesus Rodriguez
好的,抱歉,我已经更新了问题并提供了更多信息。 - Dane
1个回答

5

这个问题即将迎来一周年纪念,我觉得很有趣的是为什么测试不能通过。

我得出的结论是测试的前提条件是错误的,因为测试

expect(scope.dropDownResponses[scope.dropDownField.name]).toBe("1");

应该是

expect(scope.dropDownResponses[scope.dropDownField.name]).toBe("2");

这是因为在scope.dropDownResponses中存储的值实际上是2,正如提问者所发现的那样。
当您选择val('1')时,实际上是选择下拉选择框中的第二个选项。
<select ng-model="dropDownResponses[dropDownField.name]" ng-options="value.key as value.value for value in dropDownField.values" class="ng-valid ng-dirty">
  <option value="0" selected="selected">FL</option>
  <option value="1">GA</option>
  <option value="2">TX</option>
</select>

这反映了规范中数组的第二个项目。

{
  "key": "2",
  "value": "GA",
  "select": "false"
},

您可以在这个 jsfiddle 中看到实际效果,其中包括console.log输出

it('should update the model when a new choice is selected', function() {
  console.log(angular.element(directive.find("select")));
  console.log('selected before = ' + angular.element(directive.find("select option:selected")).text());
  angular.element(directive.find("select")[0]).val(1);
  console.log('selected after = ' + angular.element(directive.find("select option:selected")).text());
  angular.element(directive.find("select")[0]).change();
  console.log('selected Text value = ' + angular.element(directive.find("select option:selected")).text());
  expect(scope.dropDownResponses[scope.dropDownField.name]).toBe("2");
  console.log(scope.dropDownResponses[scope.dropDownField.name]);
  //console.log('selectedIndex=' + angular.element(directive.find("select")).selectIndex());
  console.log(angular.element(directive.find("select"))[0]);
});

selected before = 
(index):98 selected after = GA
(index):100 selected Text value = GA
(index):102 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接