如何模拟polymer core ajax进行单元测试
我正在为我的新聚合物项目搭建脚手架,并且正在考虑单元测试。我想我会使用因果报应和茉莉花的组合。有一篇有趣的帖子,我对此有足够的了解,可以让我开始学习,但我必须解决的关键问题是如何模拟ajax调用,目前还没有找到任何标准的方法 当我在JQuery移动项目上使用jasmine,standalone时,我能够直接使用jasmine SpyOn功能模拟JQuery.ajax调用。聚合物也有类似的情况吗如何模拟polymer core ajax进行单元测试,ajax,unit-testing,polymer,Ajax,Unit Testing,Polymer,我正在为我的新聚合物项目搭建脚手架,并且正在考虑单元测试。我想我会使用因果报应和茉莉花的组合。有一篇有趣的帖子,我对此有足够的了解,可以让我开始学习,但我必须解决的关键问题是如何模拟ajax调用,目前还没有找到任何标准的方法 当我在JQuery移动项目上使用jasmine,standalone时,我能够直接使用jasmine SpyOn功能模拟JQuery.ajax调用。聚合物也有类似的情况吗 我遇到了一个元素,但是没有关于它的真正文档,因此我无法确定它们是否有助于而不是导入核心ajax/cor
我遇到了一个元素
,但是没有关于它的真正文档,因此我无法确定它们是否有助于而不是导入核心ajax/core ajax.html
,创建您自己的核心ajax元素
<polymer-element name="core-ajax" attributes="response">
<script>
Polymer('core-ajax', {
attached: function() {
this.response = ['a', 'b', 'c'];
}
});
</script>
</polymer-element>
聚合物(“核心-ajax”{
附:函数(){
this.response=['a','b','c'];
}
});
显然,这只是一个示例,实际实现取决于所需的模拟行为
这只是解决问题的一种方法,还有很多其他方法。我很想听听你觉得方便些什么。事实证明,Jasmine2.0有一个Jasmine ajax插件,可以模拟全局XMLHttpRequest。CoreAJAX在幕后使用它,所以我可以直接接到电话 它工作得很好,在调用jasmine.Ajax.install的套件顶部的
beforeach
函数中,以及在调用jasmine.Ajax.uninstall
函数之后的函数中,它会自动替换XMLHttpRequest
计时也很重要,因为您需要确保在被测元素使用Ajax调用之前已经模拟了它。我使用一个单独的函数专门加载包含被测元素的fixture,该fixture在调用jasmine.Ajax.install
后被调用。因此,我使用了一个特殊的设置脚本
(function(){
var PolymerTests = {};
//I am not sure if we can just do this once, or for every test. I am hoping just once
var script = document.createElement("script");
script.src = "/base/components/platform/platform.js";
document.getElementsByTagName("head")[0].appendChild(script);
var POLYMER_READY = false;
var container; //Used to hold fixture
PolymerTests.loadFixture = function(fixture,done) {
window.addEventListener('polymer-ready', function(){
POLYMER_READY = true;
done();
});
container = document.createElement("div");
container.innerHTML = window.__html__[fixture];
document.body.appendChild(container);
if (POLYMER_READY) done();
};
//After every test, we remove the fixture
afterEach(function(){
document.body.removeChild(container);
});
window.PolymerTests = PolymerTests;
})();
这里需要注意的唯一一点是,夹具文件已由karma html2js预处理器加载,该预处理器将它们加载到窗口中
我的测试套件就是这样
describe('<smf-auth>',function(){
beforeEach(function(done){
jasmine.Ajax.install();
PolymerTests.loadFixture('client/smf-auth/smf-auth-fixture.html',done);
});
afterEach(function(){
jasmine.Ajax.uninstall();
});
describe("The element authenticates",function(){
it("Should Make an Ajax Request to the url given in the login Attribute",function(){
var req = jasmine.Ajax.requests;
expect(req.mostRecent().url).toBe('/football/auth_json.php'); //Url declared in our fixture
});
})
});
描述(“”,函数(){
每次之前(功能完成){
jasmine.Ajax.install();
loadFixture('client/smf auth/smf auth fixture.html',完成);
});
之后(函数(){
jasmine.Ajax.uninstall();
});
描述(“元素身份验证”,函数(){
它(“应该对登录属性中给定的url发出Ajax请求”,function(){
var req=jasmine.Ajax.requests;
expect(req.mostRecent().url).toBe('/football/auth_json.php');//在我们的fixture中声明的url
});
})
});
对于这个答案,我采取了完全不同的方法。灵感来自Web组件测试仪,它将sinon包括在其能力范围内。sinon包括调用sinon.usefakeMlHttpRequest以替换core ajax使用的标准xhr对象并返回相应响应的功能
据我所见,还没有使用它运行模块测试,Web Component Tester在node.js上下文中运行sinon,因此随它提供的sinon构建可以“需要”各种sinon组件。在正常的浏览器环境中,这不起作用,我正在寻找一种方法,允许我在没有运行php服务器的情况下手动运行我正在开发的应用程序
然而,从sinonjs.org网站下载并安装Bower的实际版本确实提供了一个完全构建的sinon,它将在web服务器的上下文中运行
因此,我可以在我的主index.html文件中包含以下脚本
它会被gulp build scrips自动删除,然后fake JS包含以下内容
var PAS=(函数(my){
"严格使用",;
my.Faker=my.Faker | |{};
var getLocation=函数(href){
var a=document.createElement('a');
a、 href=href;
返回a;
};
sinon.FakeXMLHttpRequest.useFilters=true;
sinon.FakeXMLHttpRequest.addFilter(函数(方法,url){
if(方法=='POST'&&getLocation(url).pathname.substring(0,7)=='/service/')){
返回false;
}
返回true;
});
var server=sinon.fakeServer.create();
server.autoRespond=true;
my.Faker.addRoute=函数(路由、参数、未找到){
server.respondWith('POST','/service/'+route+'.php',函数(请求){
var postParams=JSON.parse(request.requestBody);
var foundMatch=false;
var-allMatch;
/*
*首先,我们将通过参数列表查看是否有参数
*它与从我们的帖子中收到的参数匹配。如果参数的所有组件都匹配,
*然后我们找到了一个
*/
对于(var i=0;i对于0.8,演示如何使用sinon实现这一点
由于SO不喜欢只链接的答案,我将他们的代码复制到了下面。但是我强烈建议访问上面链接的源代码,因为0.8组件目前处于高流量状态
var jsonResponseHeaders = {
'Content-Type': 'application/json'
};
var ajax;
var request;
var server;
setup(function () {
server = sinon.fakeServer.create();
server.respondWith(
'GET',
'/responds_to_get_with_json',
[
200,
jsonResponseHeaders,
'{"success":true}'
]
);
server.respondWith(
'POST',
'/responds_to_post_with_json',
[
200,
jsonResponseHeaders,
'{"post_success":true}'
]
);
ajax = fixture('TrivialGet');
});
teardown(function () {
server.restore();
});
suite('when making simple GET requests for JSON', function () {
test('has sane defaults that love you', function () {
request = ajax.generateRequest();
server.respond();
expect(request.response).to.be.ok;
expect(request.response).to.be.an('object');
expect(request.response.success).to.be.equal(true);
});
test('will be asynchronous by default', function () {
expect(ajax.toRequestOptions().async).to.be.eql(true);
});
});
谢谢-当你知道答案的时候,这是很明显的。真正能够测试第一个元素的过程有点慢,因为我正在一次学习咕噜声、因果报应和聚合物,并且只有空闲时间去做。但这对我来说是一个足够的指针,我发现这种方法在实践中相当困难-因为通常的方法是在包含元素定义的html文件中导入核心ajax,我们不想仅仅为了运行测试而改变它。我想我可能想在核心ajax原型上更改go方法,但在我的元素在ready回调中调用它之前,还不知道如何实现它。