I have been having some trouble getting the correct Express Request type working in Jest. I have a simple user registration passing with this code:
import { userRegister } from '../../controllers/user';
import { Request, Response, NextFunction } from 'express';
describe('User Registration', () => {
test('User has an invalid first name', async () => {
const mockRequest: any = {
body: {
firstName: 'J',
lastName: 'Doe',
email: '[email protected]',
password: 'Abcd1234',
passwordConfirm: 'Abcd1234',
company: 'ABC Inc.',
},
};
const mockResponse: any = {
json: jest.fn(),
status: jest.fn(),
};
const mockNext: NextFunction = jest.fn();
await userRegister(mockRequest, mockResponse, mockNext);
expect(mockNext).toHaveBeenCalledTimes(1);
expect(mockNext).toHaveBeenCalledWith(
new Error('First name must be between 2 and 50 characters')
);
});
});
However, if I change:
const mockRequest: any = {
body: {
firstName: 'J',
lastName: 'Doe',
email: '[email protected]',
password: 'Abcd1234',
passwordConfirm: 'Abcd1234',
company: 'ABC Inc.',
},
};
to:
const mockRequest: Partial<Request> = {
body: {
firstName: 'J',
lastName: 'Doe',
email: '[email protected]',
password: 'Abcd1234',
passwordConfirm: 'Abcd1234',
company: 'ABC Inc.',
},
};
From the TypeScript documentation (https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt), this should make all fields on the Request object optional.
However, I get this error:
Argument of type 'Partial<Request>' is not assignable to parameter of type 'Request'.
Property '[Symbol.asyncIterator]' is missing in type 'Partial<Request>' but required in type 'Request'.ts(2345)
stream.d.ts(101, 13): '[Symbol.asyncIterator]' is declared here.
I was hoping that someone with a little more TypeScript experience could comment and let me know what I am doing wrong.
Partial<Request>
is doing, but I'm betting that the trouble is thatuserRegister
does not acceptPartial<Request>
- it requiresRequest
right? Are you able to declare mockRequest asRequest
?const mockRequest: Partial<Request> ...
If not, you could us an assertion:await userRegister(mockRequest as Request, mockResponse, mockNext);
– Antispasmodicexport const userRegister = async ( req: express.Request, res: express.Response, next: express.NextFunction ) => {
. The mock is inside a test. I got around it for now by using:const mockRequest: any = { body: { firstName: 'J', lastName: 'Doe', email: '[email protected]', password: 'Abcd1234', passwordConfirm: 'Abcd1234', company: 'ABC Inc.', }, };
. But I was told to try not to useany
whenever possible as it defeats the purpose of TypeScript. – SimmieuserRegister
does requirereq: express.Request
andres: express.Response
. Interesting, but for testing, is there a way to get around that? I guess I became confused whenany
worked. – Simmie