使用w

时间:2015-12-11 00:47:26

标签: polymer sinon web-component-tester

我正在努力模拟服务器对自定义组件中的iron-ajax组件的响应。这是我的代码文件。

定制component.html:

<link rel="import" href="/iron-ajax/iron-ajax.html">
<link rel="import" href="/internal-component/internal-component.html">

<dom-module id="custom-component">
    <template>
        <iron-ajax url="staticFile.json" auto handle-as="json" last-response={{ajaxResponse}}></iron-ajax>
        <template is="dom-repeat"
                  items={{ajaxResponse}}
                  sort="_sort"
                  id="gridRow">
            <internal-component var1={{item.var1}}
                                   var2={{item.var2}}>
            </internal-component>
        </template>
    </template>
</dom-module>
<script>(some cool scripts that are working...)</script>

定制组件tests.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script src="/webcomponentsjs/webcomponents-lite.js"></script>
    <script src="/web-component-tester/browser.js"></script>
    <script src="/test-fixture/test-fixture-mocha.js"></script>

    <link rel="import" href="/test-fixture/test-fixture.html" />

    <link rel="import" href="/polymer/polymer.html">
    <link rel="import" href="/polymer-ts/polymer-ts.html">

    <link rel="import" href="custom-component.html">
</head>
<body>
<test-fixture id="testElement">
    <template>
        <custom-component></custom-component.>
    </template>
</test-fixture>

<script>
    suite('<custom-component>', function () {
        var testElement;
        var server;
        var responseHeaders = {
            json: { 'Content-Type': 'application/json' },
            plain: { 'Content-Type': 'text/plain' }
        };
        setup(function () {
            replace('custom-component').with('fake-custom-component');
            server = sinon.fakeServer.create();
            server.respondWith('GET', /staticFile\.json/, [
                200,
                responseHeaders.json,
                '[{"var1": "9a","var2": "17n"}]'
            ]);
            testElement = fixture("testElement");
        });
        teardown(function () {
            server.restore();
        });
        suite('testSuite', function () {
            test('test1', function () {
                var ajax = testElement.getElementsByTagName('iron-ajax')[0];
                ajax.lastResponse = null;
                ajax.generateRequest();
                server.respond();
                assert(ajax.lastResponse.hour === "9a");
            });
        });
    });
</script>

</body>
</html>

你会注意到我明确地调用了iron-ajax generateRequest,因为如果我没有,那么请求甚至不会发生,直到我的测试完成(并且失败)。当显式调用generateRequest时,我至少能够发出请求,但是(即使我正在调用server.respond())iron-ajax在测试完成之前不会调用_handleResponse。而且,即使它确实如此,它也没有设置lastResponse,因为iron-ajax中有一行代码检查if(request === this.lastRequest)(它不是)。

我做错了什么?

3 个答案:

答案 0 :(得分:4)

我找到了一个更好的解决方案来测试我的元素中的铁-ajax元素的自动功能。

您需要在ajax的请求上添加一个事件监听器来激活您的服务器响应,不需要generateRequest,也不需要setTimeout hacks。

这是一个例子:

            test('test with ajax element', function (done) {
                var ajax = Polymer.dom(myElement.root).querySelector("#ajax_element");

                ajax.addEventListener('request', function (e) {
                    server.respond('GET', '/CALLED_URL', dataResponse);
                });

                ajax.addEventListener('response', function (e) {
                    //DO YOUR EXPECTS HERE
                    done();
                });
            });

答案 1 :(得分:2)

我想我晚上睡了个好觉。

我忘了考虑异步请求。我修改了代码,现在反映如下:

suite('<custom-component>', function () {
    var testElement;
    var server;
    var responseHeaders = {
        json: { 'Content-Type': 'application/json' },
        plain: { 'Content-Type': 'text/plain' }
    };
    setup(function () {
        replace('custom-component').with('fake-custom-component');
        server = sinon.fakeServer.create();
        server.respondWith('GET', /staticFile\.json/, [
            200,
            responseHeaders.json,
            '[{"var1": "9a","var2": "17n"}]'
        ]);
        testElement = fixture("testElement");
    });
    teardown(function () {
        server.restore();
    });
    suite('testSuite', function () {
        // note that I added the "done" as a parameter on my test function
        test('test1', function (done) {
            var ajax = testElement.getElementsByTagName('iron-ajax')[0];
            ajax.generateRequest();
            server.respond();

            // note that I added an async event listener here, and moved my test inside.
            ajax.addEventListener('response', function(e) {
                assert(e.target.lastResponse.var1 === "9a");
                done();
            }
        });
    });
});

我现在能够正确拦截响应,并且测试大部分都按预期工作。我仍然存在铁 - 阿贾克斯的最后响应没有设定的问题,但我认为这是一个不同的问题。

答案 2 :(得分:0)

作为组件测试我相信你应该真正测试组件行为而不是sinon和/或iron-ajax元素内部。您的请求很可能会更新一些会触发一些DOM更新的属性。

我在测试中也一直讨厌setTimeouts,并且刚刚发现WCT对这些情况采用flush方法(等待所有异步内容完成) - 它&#39;没有记录在AJAX测试部分,而是在DOM操作上(https://www.polymer-project.org/1.0/docs/tools/tests#test-local-dom)。

因此,我的方法是:

suite('testSuite', function () {
  test('test1', function (done) {
    // assuming iron-ajax with auto
    server.respond();
    flush(function () {
      expect(el.myObject).to.deep.equal(responseObj);

      // in case you're binding the last response to a property
      expect(el.lastResponse).to.deep.equal(responseObj);

      done();
    })
  });
});