Skip to content

Instantly share code, notes, and snippets.

@amabes
Last active September 15, 2023 10:55
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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([]);
expect(service.uploadFileList(fileList)).toEqual([]);
});
@VergilSkye
Copy link

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

@neil-berg
Copy link

Thanks @kroeder! Very helpful.

@delorie
Copy link

delorie commented Jul 28, 2020

Thanks @kroeder!

@shabbir-dhangot
Copy link

getting this error

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

@CameronJThomas
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.

@deftonjke
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.name = file.name;
  blob.lastModified = Date.now();
  return blob as File;
};

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