How to test files and json data at the same time with jest?

I have a post request with express that upload a file and some data to the mongodb:

// Routes'/api/training', validator(createVideoSchema, 'body'), uploadVideo, createVideoHandler);

// Route Handlers
async function createVideoHandler (req: Request, res: Response, next: NextFunction) {
  try {
    const dataToCreate = {
      url: req.file?.path,
      mimetype: req.file?.mimetype

    const data = await service.create(dataToCreate);
    response(req, res, data, 201);
  } catch (error) {

the body must be validate by joi using the following schema:

import Joi from 'joi';

const title = Joi.string().email().min(5).max(255);
const description = Joi.string().min(5).max(255);
const thumbnail = Joi.string().min(5).max(255);
const tags = Joi.array().items(Joi.string().min(5).max(100));

const createVideoSchema = Joi.object({
  title: title.required(),
  description: description.required(),
  thumbnail: thumbnail.required(),
  tags: tags.required(),

export { createVideoSchema };

Then I am creating a test to verify I am receiving a 201 status code:

it('should have a 201 status code', async () => {
    const response = await request(app).post(route)
      .set('Accept', 'application/json')
      .field('title', data.title)
      .field('description', data.description)
      .field('thumbnail', data.thumbnail)
      .field('tags', data.tags)
      .attach('video', Buffer.from('video'), { filename: 'video.mp4' });

For some reason the validation middleware throws me a 400 error saying that the data is missing:

Error: “title” is required. “description” is required. “thumbnail” is required. “tags” is required

I tried to send the data using .set(‘Accept’, ‘multipart/form-data’) but it throws me the same error.

I guess this error has to do with the way I send the data, but I don’t fully understand.


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You typically should not call a live API from a test. Instead you should mock the different possibly API response scenarios and be sure your code handles the different possibilities correctly. Ideally you’ll also have a client class of some kind to place direct calls to your API inside a class that can easily be mocked.

For example, you could mock the endpoint response for valid data with something like:

export class VideoClient {
    async createVideo(data) {
        const response = await request(app).post(route) // Whatever url points to your API endpoint
           .set('Accept', 'application/json')
           .field('title', data.title)
           .field('description', data.description)
           .field('thumbnail', data.thumbnail)
           .field('tags', data.tags)
           .attach('video', Buffer.from('video'), { filename: 'video.mp4' });
        if (response.status.ok) {
            return { response, message: 'someGoodResponseMessage'};
        return { response, message: 'someErrorOccurred' };

Then in your test you can mock your client call:

import { VideoClient } from './clients/VideoClient.js'; // or whatever path you saved your client to
const goodData = { someValidData: 'test' };
const badData = {someBadData: 'test' };
const goodResponse = {
    response: { status: 201 },
    message: 'someGoodResponseMessage'
const badResponse = {
    response: { status: 400 },
    message: 'someErrorOccurred'

it('should have a 201 status code', async () => {
    VideoClient.createVideo = jest.fn().mockReturnValue(goodResponse);
    const results = await VideoClient.createVideo(goodData);

it('should have a 400 status code', async () => {
    VideoClient.createVideo = jest.fn().mockReturnValue(badResponse);
    const results = await VideoClient.createVideo(badData);


This is by no means a working test or exhaustive example, but demonstrating the idea that you really should not call your API in your tests, but instead call mock implementations of your API to handle how your client code responds in different situations.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x