TypeScript - FileReader başarısızlığını nasıl taklit ederim
Bir FileReader oluşturan bir fonksiyonum var. Bu fonksiyonda ayrıca load ve error olay işleyicilerini de ayarlıyorum.
handleFileSelect(files:ArrayLike<File>){
...
let reader = new FileReader()
reader.onload = this.handleReaderLoaded;
reader.onerror = this.handleReaderError;
reader.readAsDataURL(file);
}
}
Ben, handleFileSelect'in hata işleyiciyi doğru bir şekilde ayarladığını ve FileReader başarısız olursa hata işleyicinin (handleReaderError) çağrıldığını birim test ile test etmek istiyorum. Ama FileReader'ı nasıl başarısız yapacağımı bir türlü bulamıyorum.
Şimdiye kadar yazdığım spesifikasyon
fit('should call error handler when file doesn\'t get loaded successfully', (done) => {
let newPracticeQuestionComponent = component;
let file1 = new File(["foo1"], "foo1.txt");
/*
File reader will load the file asynchronously.
The `done` method of `Jasmine` makes `Jasmine` wait
When handleReaderError is called, call a fake function and within it call done
*/
spyOn(newPracticeQuestionComponent,'handleReaderError').and.callFake(function(event:FileReaderProgressEvent){
console.log("called fake implementation of handleReaderError ",event);
expect(event.type).toEqual("abort");
done();
});
newPracticeQuestionComponent.handleFileSelect([file1]);
//I SHOULD SIMULATE FILEREADER ERROR HERE BUT HOW??
});
Cevap #1
Zaten readAsDataURL metodunu taklit edebileceğimiz ve ondan hata olayını gönderebileceğimiz söylenmişti. Ama sizin okuyucunuz handleFileSelect fonksiyonundaki bir yerel değişken. Okuyucuya erişmek için FileReader yapıcısını taklit edebilir ve oluşturulan dosya okuyucu örneğinin kontrolünü alabiliriz. Burada taklit için sinon kullanıyorum:
// in your test:
...
// This is the reader instance that we have access
const reader = new FileReader()
// We throw an error in readAsArrayBuffer method of that instance
reader.readAsArrayBuffer = () => {
reader.dispatchEvent(new Event('error'))
}
// Now make the constructor return our instance
sinon.stub(window, 'FileReader').returns(r)
// Now make your calls and assertions
...
// Don't forget to restore the original constructor at the end
window.FileReader.restore()
Cevap #2
Eğer readerın davranışı readAsDataURL başarısız olduğunda onerror çağırmaksa, bu yapılmalıdır:
spyOn(newPracticeQuestionComponent.reader, 'readAsDataURL').and.callFake(() => {
newPracticeQuestionComponent.reader.onerror();
});
Bu, eşzamanlı bir çağrı olarak çalışacağından, testin sonunda (üçlü A'dan sonra) yapılan doğrulamayı şu şekilde basitleştirebilirsiniz:
// Arrange
const newPracticeQuestionComponent = component;
spyOn(newPracticeQuestionComponent, 'handleReaderError');
spyOn(newPracticeQuestionComponent.reader, 'readAsDataURL').and.callFake(() => {
newPracticeQuestionComponent.reader.onerror();
});
let file1 = new File(["foo1"], "foo1.txt");
// Act
newPracticeQuestionComponent.handleFileSelect([file1]);
// Assert
expect(newPracticeQuestionComponent.handleReaderError).toHaveBeenCalledWith({ type: 'abort' });
Ama fonksiyona geçen parametrenin, event.type, beklenmesini önermem çünkü bu şu anda test etmediğimiz başka bir birimin spesifikasyonudur. (biz newPracticeQuestionComponent’i test ediyoruz, reader’ın bir hatayı bir event ile çağırma davranışını değil)
reader davranışını taklit etmek en iyi yol olmayabilir. Birim karşısında neyi test etmek istediğinize bağlıdır.
Eğer tamamen bağımsız olmak istiyorsak, newPracticeQuestionComponent reader’ın davranışı hakkında hiçbir şey bilmemelidir, hatta callback hatası hakkında bile, bu birimin bilmesi gereken tek şey onerror callback'ini ayarlamaktır, sadece reader'ın onerror’ını doğru şekilde ayarladığını doğrulayabilirsiniz.
// Arrange
const newPracticeQuestionComponent = component;
spyOn(newPracticeQuestionComponent.reader, 'readAsDataURL');
let file1 = new File(["foo1"], "foo1.txt");
// Act
newPracticeQuestionComponent.handleFileSelect([file1]);
// Assert
expect(newPracticeQuestionComponent.reader.onerror).toBe(newPracticeQuestionComponent.handleReaderError);
Test yapma konusunda bir usta değilim, ama yukarıdaki ve aşağıdaki örnekler gibi testler yazmanın birçok faktöre bağlı olarak avantajları ve dezavantajları olduğu görünüyor.
Umarım bu yardımcı olur :)
