Search code examples
unit-testingwebpackkarma-jasmine

How can I load binary files in a Jasmine/Karma test?


I have an Angular project that parses binary files from user input. This makes unit testing difficult. I'd like to be able to include these files in my Jasmine/Karma tests which are run in a browser.

I have found that I am able to use Karma's files property to get these files included into Karma so they can be loaded.

karma.conf.js

files: [
  {
    pattern: "sample-files/*.sbsong",
    watched: false,
    served: true,
    included: false,
  },
],

Now I try to load this file into a test like this

it('should parse a binary file', () =>{
  const file  = require('/sample-files/song1.sbsong');
  
  const parsedFile = parser(file);
  expect(parsedFile).toEqual('foo');
});

This generates an error, however it also confirms that the file path is correct and it sees the file

./sample-files/song1.sbsong:1:0 - Error: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

This feels like it's so close, but how can I get karma or webpack to just give me the data of this file so I can pass it on to my parser for a unit test? Currently it seems to be trying to load these files as a javascript module, but I just want to get the raw file contents.


Solution

  • In the opensource project Koia.io, I load an Excel file to be used in a Jasmine unit test defined inside excel-reader.spec.ts.

    To do so, I had to define the file inside karma.conf.js as follows:

    files: [
       ...  
       { 
         pattern: 'src/app/shared/services/reader/excel/test.xlsx', 
         included: false, 
         watched: false, 
         served: true 
       }
    ]
    

    The relevant function in excel-reader.spec.ts is loadExcelFile.

    async function loadExcelFile(): Promise<File> {
      const response = await fetch(EXCEL_FILE_URL);
      const blob = await response.blob();
      return new File([blob], 'test.xlsx');
    }
    

    I think, a similar approach should also work in your case. If you don't need a file, simply let the function return the Blob.