question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to test/simulate file upload from nodeJs unit/integration test?

See original GitHub issue

I would like to test my GraphQL endpoint, for that I created a test client based on request-promise-native. This works for all mutations, but not when it has an Upload type. I studied the unit testing code in this library, but could not figure it out.

I want to programatically upload a file and send it with form data. My current solution always has a file value of null on the receiving side.

Preparing the file for formData:

const file: any = fs.createReadStream('./a.txt');
const f = Promise.resolve({
      stream: file,
      filename: 'a.txt',
      mimetype: 'application/pdf',
      encoding: '7bit',
    });

In my formData (the query and variables are inserted before, but that is not the problem

const formData: any = {
      operations: `{ "query": "${query}", ${variables} }`,
      map: '{ "file0": ["variables.file"] }',
      file0: {
        value: f,
        options: {
          filename: 'a.txt',
          contentType: 'application/txt',
        },
      },
    };

Please help!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
awilderinkcommented, Oct 25, 2019

@dionnyprensa I created a little helper for this to use in my tests:

import { contentType } from 'mime-types'
import { extname } from 'path';
import app from '@/app'
import * as supertest from 'supertest'

const graphql = (query: string, variables: { [x: string]: any } = {}) => {
  const map = Object.assign({}, Object.keys(variables).map(key => [`variables.${key}`]));
  const request = supertest(app)
    .post('/graphql')
    .field('operations', JSON.stringify({ query }))
    .field('map', JSON.stringify(map));

  Object.values(variables).forEach((value, i) => {
    if (contentType(extname(value))) {
      request.attach(`${i}`, value);
    } else {
      request.field(`${i}`, value);
    }
  });

  return request;
};

describe('Upload', () => {
  it('should return a file after uploading one', async done => {
    const res = await graphql(
      /* GraphQL */ `
        mutation($file: Upload!) {
          singleFileUpload(file: $file) {
            id
          }
        }
      `,
      { file: __dirname + '/__files/image.jpg' }
    )
    expect(res.body.data.singleFileUpload.id).toBeDefined()
    done()
  })
})

I use it together with apollo-server-express and Jest, but I think it might work for you aswell. It may even work with regular queries, but I haven’t tested that yet.

5reactions
jaydensericcommented, Nov 21, 2018

You can find inspiration in the tests: https://github.com/jaydenseric/graphql-upload/blob/8d0f3e5ad144ab15eb7449e53322627eaed1d541/src/test.mjs#L77

You should only need node-fetch and form-data:

const FormData = require('form-data')
const fetch = require('node-fetch')

const body = new FormData()

body.append(
  'operations',
  JSON.stringify({
    query: /* GraphQL */ `
      mutation($file: Upload!) {
        uploadFile(file: $file) {
          id
        }
      }
    `,
    variables: {
      file: null
    }
  })
)
body.append('map', JSON.stringify({ 1: ['variables.file'] }))
body.append('1', 'a', { filename: 'a.txt' })

const response = fetch('http://localhost:3001', { method: 'POST', body })

I find it easier to create files in the test itself rather than use fs:

- body.append('1', 'a', { filename: 'a.txt' })
+ body.append('1', fs.createReadStream('./a.txt'))
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to unit test with a file upload in mocha - Stack Overflow
I have an app built on Express.js and I'd like to test the file upload functionality. I'm trying to reproduce the object parsed...
Read more >
Unit-Testing REST API File Upload with Jest, Supertest and ...
In the tests, we will upload the test file to the CDN host, rename it, and delete it in the end. And the...
Read more >
WRITING TESTS FOR IMAGE/FILE UPLOADS IN NODEJS.
This article demonstrates how to upload single and multiple files in nodejs.
Read more >
Unit and integration testing for Node.js apps - LogRocket Blog
This post is going to introduce unit and integration testing of Node.js applications. We're going to be reviewing my Express.js API ...
Read more >
Unit Testing and Integration Testing Nestjs Application
Jest ships as an NPM package, you can install it in any JavaScript project. Jest is one of the most popular test runner...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found