La risposta qui dipende un po '. Il tuo metodo "generateThumbs" ha altra logica che caricare un contenuto di file e assegnarlo a una proprietà di un oggetto passato? Oppure ha altre logiche come generare l'anteprima dai dati dell'immagine, leggere le proprietà dei file e assegnarle all'oggetto file? e così via?
In tal caso, quindi, suggerirei di prendere in giro l'oggetto FileReader con il proprio, in modo da poter controllare i risultati del test. Tuttavia, non è la funzionalità FileReaders che desideri testare, è la tua logica. Quindi dovresti assumere che FileReader funzioni e verifica che il tuo codice che dipende da esso funzioni.
Ora, poiché il metodo che hai postato era un po 'piccolo, in tal caso supponevo che funzionasse, rinominare il metodo e lavorare sul test del resto del codice. Ma c'è un posto per avere un tale finto, e devo ammettere che è stato molto divertente per capire come per deridere il target dell'evento, quindi mi darà un esempio qui, utilizzando il metodo di come base:
//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);
});
}
Ora abbiamo un piccolo oggetto che si comporta come un FileReader, ma controlliamo il suo comportamento e ora possiamo usare il nostro metodo e iniettarlo, consentendoci così di usare questo simulato per i test e la cosa reale per la produzione.
Così possiamo ora scrivere unit test belle per testare questo fuori: presumo di avere moka e configurazione chai
describe('The generateThumb function', function() {
var file = { src: 'image.file'};
var readerSpy = {};
var testData = 'TESTDATA';
var reader = new FakeFileReader(readerSpy, testData);
it('should call the readAsDataURL function when given a file name and a FileReader', function() {
generateThumb(file, reader);
expect(readerSpy.calledReadAsDataURL).to.be.true;
expect(readerSpy.loaded).to.be.true;
});
it('should load the file and convert the data to base64', function() {
var expectedData = 'VEVTVERBVEE=';
generateThumb(file, reader);
expect(readerSpy.file.src).to.equal(file.src);
expect(readerSpy.file.dataUrl).to.equal(expectedData);
});
});
Ecco un JSFiddle lavora esempio: https://jsfiddle.net/workingClassHacker/jL4xpwwv/2/
I vantaggi qui sono è possibile creare diverse versioni di questo simulato:
- cosa succede quando vengono dati dati corretti?
- cosa succede quando vengono dati dati errati?
- cosa succede quando la richiamata non viene mai chiamata?
- cosa succede quando viene inserito un file troppo grande?
- cosa succede quando viene inserito un certo tipo di mimo?
È possibile offcourse massicciamente semplificare il mock se tutto ciò che serve è che un evento:
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);
}
che è come mi sarebbe effettivamente fare questo. E creare molti di questi per scopi diversi.
Versione semplice: https://jsfiddle.net/workingClassHacker/7g44h9fj/3/
mi chiedo la stessa cosa pure. – frogbandit