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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22157164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 22:33:52  来源:igfitidea点击:

How to unit test a dropdown list in Jasmine/Angularjs

javascriptangularjsunit-testingjasmine

提问by Dane

I am trying to unit test a directive that makes a dropdown list using some JSON to specify the details of the list. The directive works fine, but I'm having issues while trying to unit test it.

我正在尝试对使用一些 JSON 生成下拉列表的指令进行单元测试,以指定列表的详细信息。该指令工作正常,但我在尝试对其进行单元测试时遇到问题。

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.

最后一个 it 块是这里关注的内容。当我触发更改事件时,模型上的值总是比预期的多一个。例如,在这种情况下,存储在 scope.dropDownResponses 中的值最终为 2。

Any ideas?

有任何想法吗?

回答by Nicholas Murray

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 元素中的第二个选项

<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 jsfiddlewhere 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