使用mocha和html5文件api进行Javascript测试?
我在一个网站上有一个简单的图像上传程序和一个javascript函数,它使用使用mocha和html5文件api进行Javascript测试?,javascript,mocha.js,filereader,html5-filesystem,Javascript,Mocha.js,Filereader,Html5 Filesystem,我在一个网站上有一个简单的图像上传程序和一个javascript函数,它使用FileReader,并将图像转换为base64来显示给用户,而无需上传到实际的服务器 function generateThumb(file) { var fileReader = new FileReader(); fileReader.readAsDataURL(file); fileReader.onload = function (e) { // Converts the
FileReader
,并将图像转换为base64来显示给用户,而无需上传到实际的服务器
function generateThumb(file) {
var fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function (e) {
// Converts the image to base64
file.dataUrl = e.target.result;
};
}
现在,我正在尝试使用
Mocha
和Chai
为这种方法编写测试。我的想法是,我想检查文件.dataUrl
是否已成功创建,并且它是base64。所以我想在测试环境中模拟本地文件(不知道如何实现)。或者我根本不应该测试它,并假设它正在工作?这里的答案取决于一点。“generateThumbs”方法除了加载文件内容并将其分配给传入对象的属性之外,还有其他逻辑吗?或者它是否具有其他逻辑,例如从图像数据生成缩略图、读取文件属性并将其分配给文件对象?等等
如果是这样的话,我实际上建议您用自己的对象模拟FileReader对象,这样您就可以控制测试结果。但是,您要测试的不是FileReader功能,而是您自己的逻辑。所以,您应该假设FileReader可以工作,并测试依赖于它的代码是否工作
现在,由于您发布的方法有点小,在这种情况下,我假设它可以工作,重命名该方法并测试其余代码。但是有一个地方可以进行这样的模拟,我必须承认,弄清楚如何模拟事件目标非常有趣,因此我将在这里举一个例子,以您的方法为基础:
//This implements the EventTarget interface
//and let's us control when, where and what triggers events
//and what they return
//it takes in a spy and some fake return data
var FakeFileReader = function(spy, fakeData) {
this.listeners = {};
this.fakeData = fakeData;
this.spy = spy;
this.addEventListener('load', function () {
this.spy.loaded = true;
});
};
//Fake version of the method we depend upon
FakeFileReader.prototype.readAsDataURL = function(file){
this.spy.calledReadAsDataURL = true;
this.spy.file = file;
this.result = this.fakeData;
this.dispatchEvent({type:'load'}); //assume file is loaded, and send event
};
FakeFileReader.prototype.listeners = null;
FakeFileReader.prototype.addEventListener = function(type, callback) {
if(!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push(callback);
};
FakeFileReader.prototype.removeEventListener = function(type, callback) {
if(!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for(var i = 0, l = stack.length; i < l; i++) {
if(stack[i] === callback){
stack.splice(i, 1);
return this.removeEventListener(type, callback);
}
}
};
FakeFileReader.prototype.dispatchEvent = function(event) {
if(!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
event.target = this;
for(var i = 0, l = stack.length; i < l; i++) {
stack[i].call(this, event);
}
};
// Your method
function generateThumb(file, reader){
reader.readAsDataURL(file);
reader.addEventListener('load', function (e) {
file.dataUrl = base64(e.target.result);
});
}
下面是一个正在工作的JSFIDLE示例:
这里的好处是,您可以创建此模拟的多个版本:
- 当给出正确的数据时会发生什么
- 当给出不正确的数据时会发生什么
- 当从未调用回调时会发生什么
- 当文件太大时会发生什么
- 当放入某个mime类型时会发生什么
function FakeFileReader(spy, testdata){
return {
readAsDataURL:function (file) {
spy.file = file;
spy.calledReadAsDataURL = true;
spy.loaded = true;
this.target = {result: testdata};
this.onload(this);
}
};
}
function generateThumb(file, reader){
reader.onload = function (e) {
file.dataUrl = base64(e.target.result);
};
reader.readAsDataURL(file);
}
我就是这样做的。并为不同的目的创建其中的几个
简单版本:
我也在想同样的事情。
function FakeFileReader(spy, testdata){
return {
readAsDataURL:function (file) {
spy.file = file;
spy.calledReadAsDataURL = true;
spy.loaded = true;
this.target = {result: testdata};
this.onload(this);
}
};
}
function generateThumb(file, reader){
reader.onload = function (e) {
file.dataUrl = base64(e.target.result);
};
reader.readAsDataURL(file);
}