聚合物单元测试模拟依赖性

时间:2014-09-29 03:28:14

标签: unit-testing polymer

我刚开始使用聚合物。我试图单元测试一个具有依赖关系的自定义元素,我想伪造/嘲笑这些。 我找到了Scott Miles关于如何模拟核心-ajax实现的建议。我认为我可以轻松地遵循该模式,但这只有在我的元素不导入要模拟的东西(在本例中为core-ajax)元素时才有效。 如果它确实导入它,那么当测试试图运行时我得到

'未捕获NotSupportedError:无法执行' registerElement' on' Document':类型' core-ajax'的注册失败。已注册具有该名称的类型。'

如果我可以做一些像document.unregister核心-ajax元素并在我的测试中再次导入它,我会更开心! 聚合物很棒但是如果我不能对其进行单元测试,那么它会带来很大的风险(至少在构建需要维护/更改的应用程序时)

你们是怎么解决这个问题的?我一直在深入研究Polymer和PolymerLab元素的回购,其中大多数都缺乏测试。到目前为止,我没有找到关于如何做的很多参考。

感谢您的帮助!

圣地亚哥

斯科茨'建议是:

不要导入core-ajax / core-ajax.html,而是创建自己的core-ajax元素。

<polymer-element name="core-ajax" attributes="response">
<script>
  Polymer('core-ajax', {
    attached: function() {
      this.response = ['a', 'b', 'c'];
    }
 });
</script>
</polymer-element>

显然,这只是一个例子,实际的实现取决于所需的模拟行为。

这只是解决问题的一种方法,还有很多其他方法。我很有兴趣听到你在(方便)找到的东西。

2 个答案:

答案 0 :(得分:1)

这个问题有点老了。图I提供了更新,因为这是一种非常常见的情况。

聚合物CLI是单元测试聚合物元素的推荐方法。它用于测试的底层库称为web-component-tester(WCT)。 WCT支持存根元素。基本上,如果您的某个测试依赖于另一个元素来返回数据,则可以创建该元素的存根,该存根始终返回一致的数据。

用于指定存根元素的单元测试代码中的JS:

setup(function() {
  replace('paper-button').with('fake-paper-button');
});

待测元素:

<dom-module id='x-el'>
  <template>
    <paper-button id="pb">button</paper-button>
  </template>
</dom-module>

在测试运行时,内容模板将标记为:

<dom-module id='x-el'>
  <template>
    <fake-paper-button id="pb">button</fake-paper-button>
  </template>
</dom-module>

https://www.polymer-project.org/1.0/docs/tools/tests#create-stub-elements

答案 1 :(得分:0)

您可以尝试使用js强制注册它,或者扩展您正在测试的每个元素,并覆盖您想要模拟的属性或方法。 我认为这就是它。这就像我的谷歌地图自定义元素,我导入谷歌地图并改变周围的东西如下:

<polymer-element name="core-gmaps" attributes="lat long mapzoom markerlat markerlong markertitle" extends="google-map">
    <template>
        <style>
        :host{
            width: 100%;
        }
        #vivaMap {
            display: block;
            height: 100%;
            width: 100%;            
        }
        </style>
        <google-map id="vivaMap" latitude="0" longitude="0" zoom="18">
            <google-map-marker id="vivaMarker" title="" latitude="0" longitude=""></google-map-marker>
        </google-map>
    </template>
    <script>

  Polymer("core-gmaps",{
    ready: function(){

        var map = this.$.vivaMap;
        map.latitude = Number(this.getAttribute('lat'));
        map.longitude = Number(this.getAttribute('long'));
        map.zoom = Number(this.getAttribute('mapzoom'));

        var mapMarker = this.$.vivaMarker;
        mapMarker.latitude = Number(this.getAttribute('markerlat'));
        mapMarker.longitude = Number(this.getAttribute('markerlong'));
        mapMarker.title = this.getAttribute('markertitle');
        /*map.addEventListener('google-map-ready', function(e) {
            console.log('Map loaded!');
        });*/
    }
  });
  </script>
</polymer-element>

我仍然不确定它是否值得专业(我最终可能不会使用它),但在理智上完全值得。学到了一些好东西。因为我正在扩展google-map,它只会注册一次。

修改
在我的情况下,我使用了ready事件,因为我本身无法操纵地图而没有至少准备好。但您可以从生命周期方法中选择事件回调。
列表为here
PS:是的,我没有使用数据绑定,因为我不能。谷歌地图api抱怨它是NaN,所以我不得不施展它。