我正在努力模拟服务器对自定义组件中的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)(它不是)。
我做错了什么?
答案 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();
})
});
});