[英]How to unit test javascript code that dynamically loads javascript files?
Suppose file1.js has a function called doSomething() that dynamically loads file2.js 假设file1.js具有一个名为doSomething()的函数,该函数可动态加载file2.js
file2.js sets a global variable window.FILE2_LOADED == true
file2.js设置一个全局变量
window.FILE2_LOADED == true
How can I write a test like below? 如何编写如下所示的测试?
describe("A Unit Test", function() {
it("can I load scripts dynamically here?", function() {
loadScript('base/file2.js');
waitForDynamicallyLoadedScriptsToLoad_IWishThisFunctionExisted(function(){
expect(window.FILE2_LOADED).equal(true);
});
});
});
UPDATE: I found some solutions (and no-solutions) that I still don't like, but think it's worth documenting. 更新:我找到了一些我仍然不喜欢的解决方案(和无解决方案),但是认为值得记录。
It's on this Github repo (it uses Mocha, not Jasmine) -> https://github.com/tonylampada/AngularJS-Testing-Article 在这个Github存储库上(它使用Mocha,而不是Jasmine)-> https://github.com/tonylampada/AngularJS-Testing-Article
You can run it with grunt test:unit
您可以使用
grunt test:unit
运行它
The relevant code is in dynamic_load_test.js 相关代码在dynamic_load_test.js中
describe("Unit: dynamic loading scripts", function() {
it("method 1 works, but using setTimeout and done is still ugly"+
"also, it may interfere with other tests", function(done) {
console.log('----------- method 1 -------------');
window.ACOUNTER = undefined;
loadScript('base/app/scripts/file2.js');
setTimeout(function(){
console.log('m1_2: '+window.ACOUNTER);
expect(window.ACOUNTER).equal(1);
done()
}, 1000)
console.log('m1_1: '+window.ACOUNTER);
});
it("method 2 works too, but I don't wanna have acces to the callback", function() {
window.ACOUNTER = undefined;
console.log('----------- method 2 -------------');
loadScript('base/app/scripts/file2.js', function(){
console.log('m2_2: '+window.ACOUNTER);
expect(window.ACOUNTER).equal(1);
});
console.log('m2_1: '+window.ACOUNTER);
});
it("method 3, doesn't work", function() {
window.ACOUNTER = undefined;
console.log('----------- method 3 -------------');
loadScript('base/app/scripts/file2.js');
describe("wait for all async to finish", function(){
it("now it will be loaded", function(){
console.log('m3_2: '+window.ACOUNTER);
expect(window.ACOUNTER).equal(1);
})
})
console.log('m3_1: '+window.ACOUNTER);
});
it("method 4, use jquery. Callback is never invoked.", function() {
window.ACOUNTER = undefined;
console.log('----------- method 4 -------------');
loadScript('base/app/scripts/file2.js');
$(document).ajaxStop(function () {
console.log('m4_2: '+window.ACOUNTER);
expect(window.ACOUNTER).equal(1);
});
console.log('m4_1: '+window.ACOUNTER);
});
});
Jasmine supports asynchronous tests: https://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support Jasmine支持异步测试: https : //jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
I would also have the path to the file to be loaded set through an argument to a function, so that you could load some simple mock file instead of an entire (supposedly requiring some other dependencies) script. 我还将通过函数的参数设置要加载文件的路径,以便您可以加载一些简单的模拟文件,而不是整个脚本(可能需要一些其他依赖项)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.