I am trying to test a file upload mutation in my GraphQL server using Supertest. server: Nestjs+GraphQL FYI: The API is working fine with appolo graphql client and postman.
However, I keep getting the following error:
Error: cannot POST /graphql (500)
at Response.toError (/src/node_modules/superagent/src/node/response.js:110:17)
at Response._setStatusProperties (/src/node_modules/superagent/src/response-base.js:107:48)
at new Response (/src/node_modules/superagent/src/node/response.js:41:8)
at Test._emitResponse (/src/node_modules/superagent/src/node/index.js:953:20)
at IncomingMessage.<anonymous> (/src/node_modules/superagent/src/node/index.js:1166:38)
at IncomingMessage.emit (node:events:525:35)
at IncomingMessage.emit (node:domain:489:12)
at endReadableNT (node:internal/streams/readable:1358:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
status: 500,
text: 'POST body missing. Did you forget use body-parser middleware?',
method: 'POST',
path: '/graphql'
}
The mutation should work as expected and process the file upload successfully.
Here is the test code I am using:
const filePath = path.join(__dirname, '1.png');
const serverInstance = await integrationTestManager.getServerInstance()
const graphqlRequest = request(serverInstance).post('/graphql')
.field('operations', jsonRequestBodyString)
.set('Content-Type', 'multipart/form-data')
.field("map", JSON.stringify({
"0": ["variables.picUpload"],
}))
.attach("0", filePath)
.set('Authorization', testingContext.users[user].token);
const testResponse = await graphqlRequest;
500 Internal Server Error
POST body missing. Did you forget use body-parser middleware?
multipart/form-data
for handling file uploads, and the GraphQL setup is configured with Apollo Server
.server file
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors';
import { graphqlUploadExpress } from 'graphql-upload';
import { ConfigService } from './common/config/config.service';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import * as bodyParser from 'body-parser';
const config: ConfigService = new ConfigService(`.env.${process.env.NODE_ENV}`);
async function bootstrap() {
try {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const port = process.env.PORT || config.get('PORT');
// app.useStaticAssets(join(__dirname, '..', 'public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.getHttpAdapter().getInstance().disable('x-powered-by');
app.use(graphqlUploadExpress({ maxFileSize: 5242880, maxFiles: 10 }));
app.setBaseViewsDir(join(__dirname, '../..', 'src/views'));
app.setViewEngine('ejs');
app.use(cors());
console.log('port :>> ', port);
await app.listen(port);
console.log(`App running on port ${port}`)
} catch (error) {
return { error }
}
}
bootstrap();
Any insights or solutions to resolve this issue would be greatly appreciated!
I don't see the whole test but I assume that you have something like this:
let app: INestApplication;
beforeEach(async () => {
const module = await Test.createTestingModule({ imports: [AppModule] })
.compile();
app = module.createNestApplication();
// etc..
});
If so, the graphqlUpload middleware won't be added to your application created during test. As I can see you add it in bootstrap tho, so that may explain why it works outside tests.
If my guess is correct you should add middleware to your test too. For example:
let app: INestApplication;
beforeEach(async () => {
const module = await Test.createTestingModule({ imports: [AppModule] })
.compile();
app = module.createNestApplication();
app.use(graphqlUploadExpress({ maxFileSize: 5242880, maxFiles: 10 }))
// etc..
});
If it won't help could you please share implementation of integrationTestManager.getServerInstance()
?