Skip to content

Instantly share code, notes, and snippets.

Last active September 15, 2023 10:55
Show Gist options
  • Save amabes/88324d68690e0e7b8e313cd0cafaa219 to your computer and use it in GitHub Desktop.
Save amabes/88324d68690e0e7b8e313cd0cafaa219 to your computer and use it in GitHub Desktop.
Simplified example to demonstrate how to Mock a FileList for unit testing purposes.
// Method to test
public uploadFileList(files: FileList) {
// whatever
// Test
it("uploadFileList", () => {
const blob = new Blob([""], { type: "text/html" });
blob["lastModifiedDate"] = "";
blob["name"] = "filename";
const file = <File>blob;
const fileList = {
0: file,
1: file,
length: 2,
item: (index: number) => file
const spy = spyOn(service, "uploadFileList").and.returnValue([]);
Copy link

kroeder commented Mar 18, 2020

Thanks for saving my day 🎉

I implemented a more dynamic way using your approach

interface MockFile {
    name: string;
    body: string;
    mimeType: string;

const createFileFromMockFile = (file: MockFile): File => {
    const blob = new Blob([file.body], { type: file.mimeType }) as any;
    blob['lastModifiedDate'] = new Date();
    blob['name'] =;
    return blob as File;

const createMockFileList = (files: MockFile[]) => {
    const fileList: FileList = {
        length: files.length,
        item(index: number): File {
            return fileList[index];
    files.forEach((file, index) => fileList[index] = createFileFromMockFile(file));

    return fileList;

How to use

/* Just some random test I need */
it('should convert a text file', async () => {
    const service: DocumentService = TestBed.get(DocumentService);

    const fileList = createMockFileList([
            body: 'test',
            mimeType: 'text/plain',
            name: 'test.txt'

    const convertedFiles = await service.convertFilesToModelDocuments(fileList);

            name: 'test.txt',
            body: 'dGVzdA==',
            mimeType: 'text/plain'

Hope this helps!

Copy link

Thank soo much! I almost lost one hour trying to do "files = new FileList()" without success

Copy link

Thanks @kroeder! Very helpful.

Copy link

delorie commented Jul 28, 2020

Thanks @kroeder!

Copy link

getting this error

Property '[Symbol.iterator]' is missing in type '{ length: number; item(index: number): File; }' but required in type 'FileList'

Copy link

Depending on the use case, a much simpler - and cleaner - way of handling this is to use a Jasmine spy. For example, I needed to mock a DragEvent for testing my drag & drop handlers. For this, we can instantiate a DataTransfer and that comes with a FileList of its own, which makes this possible:

const fileList = [{ name: 'Example File' }, { name: 'Another File' }]; 
const dataTransfer = new DataTransfer();
const dragEvent = { dataTransfer } as DragEvent;

spyOnProperty(dataTransfer, 'files').and.returnValue(fileList);

If you have a use case in which a FileList is unavoidable, I would recommend seeing if there's a relevant object you can instantiate and spy on. That way you don't have to worry about effectively "replicating" the structure of the FileList, which would likely cause TS errors if any new fields are added to FileList in future.

Copy link

Additional typing of blob was required.

interface iBlob extends Blob, File {
  name: string;
  lastModifiedDate: Date;
  lastModified: number;
  webkitRelativePathts: string;

const createFileFromMockFile = (file: MockFile): File => {
  const blob: Partial<iBlob> = new Blob([file.body], { type: file.mimeType });
  blob.lastModifiedDate = new Date(); =;
  blob.lastModified =;
  return blob as File;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment