简体   繁体   English

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

[英]How to unit test a dropdown list in Jasmine/Angularjs

I am trying to unit test a directive that makes a dropdown list using some JSON to specify the details of the list. 我正在尝试对使用某个JSON来创建下拉列表的指令进行单元测试,以指定列表的详细信息。 The directive works fine, but I'm having issues while trying to unit test it. 该指令可以正常工作,但是在尝试对其进行单元测试时遇到了问题。

Here's the test: 这是测试:

/* 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");
    });
  });
});

Here's the directive: 这是指令:

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;
});

Here's the markup: 这是标记:

<div>
  {{dropDownField.name}}
  <select ng-model="dropDownResponses[dropDownField.name]" ng-options="value.key as value.value for value in dropDownField.values"></select>
</div>

The last it block is what is of concern here. 最后一个块是这里值得关注的。 When I fire the change event, the value on the model always winds up being one more that expected. 当我触发变更事件时,模型上的值总会比期望值大一。 For instance, the value stored in scope.dropDownResponses in this case winds up being 2. 例如,在这种情况下,存储在scope.dropDownResponses中的值最终为2。

Any ideas? 有任何想法吗?

Its coming up to this questions first birthday and I found it intriguing as to why the test is not passing. 它在第一个生日刚到这个问题时就来了,我发现它对为什么测试不及格很有趣。

I have come to the conclusion that the premise of the test is wrong as the test 我得出的结论是,测试的前提是错误的测试

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

should be 应该

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

The reason for this is that the the value stored in scope.dropDownResponses is in fact 2 as the questioner found. 原因是,发问者发现,存储在scope.dropDownResponses中的值实际上是2。

When you are selecting by val('1') you are selecting the second option in the select element 当您通过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>

which reflects the second item in the array in the spec 这反映了规范中数组的第二项

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

You can see this in action in this jsfiddle where the console.log output 您可以在此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]);
});

is

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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