聚合物单元测试:调用 dom-repeat 时不渲染 "ready"



我对我的自定义聚合物组件进行了以下单元测试:

<head>
  <meta charset="UTF-8">
  <title>survey</title>
  <script src="../bower_components/webcomponentsjs/webcomponents.js"></script>
  <script src="/web-component-tester/browser.js"></script>
  <script src="../bower_components/test-fixture/test-fixture-mocha.js"></script>
  <link rel="import" href="../bower_components/polymer/polymer.html">
  <link rel="import" href="../bower_components/test-fixture/test-fixture.html">
  <link rel="import" href="../bower_components/iron-test-helpers/iron-test-helpers.html">
  <link rel="import" href="../views/components/survey.html">
</head>
<body>
  <test-fixture id="Network">
    <template>
      <survey></survey>
    </template>
  </test-fixture>
  <script>
    describe('<survey>', function() {
      var survey;
      describe('network', function() {
        beforeEach(function(done) {
          survey = fixture('Network');
        })
        it('should work', function() {
          expect(survey.$.dog).to.exist;
        });
      });
    });
  </script>

和以下自定义聚合物survey组分:

<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<dom-module id="survey">
<template>
  <h3 class="text-center">Tell us about yourself!</h3>
  <div class="form-group">
    <label>I'm a...</label>
    <array-selector id="imaSelector" items="{{ima}}" selected="{{imaSelected}}" multi toggle></array-selector>
    <template is="dom-repeat" id="imaList" items="{{ima}}">
      <div class="checkbox">
        <paper-checkbox id="{{item.id}}" on-iron-change="toggleIma">{{item.name}}</paper-checkbox>
      </div>
    </template>
  </div>
</template>
</dom-module>
<script>
  Polymer({
    is: 'survey',
    properties: {
      ima: {
        type: Array,
        value: function() {
          return [ {
            name: 'House Cat',
            id: 'houseCat'
          }, {
            name: 'Basic Dog',
            id: 'dog'
          }, {
            name: 'Swimming Fish',
            id: 'fish'
          }];
        }
      },
    
    },
    toggleIma: function(e) {
      var item = this.$.imaList.itemForElement(e.target);
      if (item) {
        this.$.imaSelector.select(item.id);
      }
    }
  })
</script>

这个测试将失败,因为本地dom没有初始化,因为我使用的是dom-repeat元素。

我怎么想,直到本地dom盖章?

这有两个部分。等待异步渲染,并找到节点。

对于渲染:要么从dom-repeat模板侦听dom-change事件,要么调用dom-repeat上的render()方法强制同步渲染。

在单元测试中,您可能只想调用render()

用于查找节点——this.$仅使用静态创建的元素填充(例如,不是来自dom-ifdom-repeat模板的元素),如文档中所述。这是一个经常引起混淆的原因。

您可以使用this.$$方便方法通过选择器查询本地DOM元素,因此您可以这样做:

survey.$.imaList.render();
expect(survey.$$(#dog)).to.exist;

您可以返回Promise,而不是立即期望:

it('should work', function() {
    return expect(survey.$.dog).should.eventually.exist();
});

这似乎是一个聚合物问题。问题是我试图使用this.$选择器来引用动态创建的节点。然而,聚合物文档明确指出,this.$将只包括静态创建的节点,而不包括动态创建的节点。

见此链接中的注释。这是针对0.5版本的,但我假设在1.0版本中也是如此。如果有任何其他已知的解决方案,而不是在链接中提到的,我很乐意听到他们。

https://www.polymer-project.org/0.5/docs/polymer/polymer.html automatic-node-finding

注意最终的解决方案,看起来像这样:

  
describe('network', function() {
  beforeEach(function(done) {
    survey = fixture('Network');
    flush(function(){
        done()
    });
  })
  it('should work', function() {
    expect(survey.querySelector('#dog')).to.exist;
  });
});

注意需要flush()来确保dom被加载。https://www.polymer-project.org/0.5/articles/unit-testing-elements.html wct-specific-helpers

最新更新