title: How to provide mock files to change event of <input type='file'> for unit testing
body: <p>I'm having difficulties with a unit test in which I want to verify the processing of a file, which would usually be selected in the view via <code>&lt;input type='file'&gt;</code>.</p>
  
  <p>In the controller part of my AngularJS app the file is processed inside the input's change event like so:</p>
  
  <pre><code>//bind the change event of the file input and process the selected file
  inputElement.on("change", function (evt) {
      var fileList = evt.target.files;
      var selectedFile = fileList[0];
      if (selectedFile.size &gt; 500000) {
          alert('File too big!');
      // ...
  </code></pre>
  
  <p>I'd like <code>evt.target.files</code> to contain my mock data instead of the user's selected file in my unit test. I realized that I can't instantiate a <code>FileList</code> and <code>File</code> object by myself, which would be the according objects the browser is working with. So I went with assigning a mock FileList to the input's <code>files</code> property and triggering the change event manually:</p>
  
  <pre><code>describe('document upload:', function () {
      var input;
  
      beforeEach(function () {
          input = angular.element("&lt;input type='file' id='file' accept='image/*'&gt;");
          spyOn(document, 'getElementById').andReturn(input);
          createController();
      });
  
      it('should check file size of the selected file', function () {
          var file = {
              name: "test.png",
              size: 500001,
              type: "image/png"
          };
  
          var fileList = {
              0: file,
              length: 1,
              item: function (index) { return file; }
          };
  
          input.files = fileList; // assign the mock files to the input element 
          input.triggerHandler("change"); // trigger the change event
  
          expect(window.alert).toHaveBeenCalledWith('File too big!');
      });
  </code></pre>
  
  <p>Unfortunately, this causes the following error in the controller which shows that this attempt failed because the files were not assigned to the input element at all:</p>
  
  <blockquote>
    <p><strong>TypeError: 'undefined' is not an object (evaluating 'evt.target.files')</strong></p>
  </blockquote>
  
  <p>I already found out that the <code>input.files</code> property is <strong>read-only</strong> for security reasons. So I started another approach by dispatching a customized change which would provide the files property, but still without success.</p>
  
  <p><strong>So long story short: I'd be eager to learn a working solution or any best practices on how to approach this test case.</strong></p>