I am trying to use jest to mock an imported class inside a typescript class, the following code is used for the main program(I removed some code from inside the functions but it shoud still be clear what I am trying to do)
import * as SocketIO from "socket.io";
import {AuthenticatedDao} from "../../dao/authenticated.dao";
export default class AuthenticationService {
private readonly _authenticatedDao: AuthenticatedDao = AuthenticatedDao.Instance;
private readonly _io;
constructor(socketIo: SocketIO.Server) {
this._io = socketIo;
}
public authenticateUser(username: string, password: string, clientSocketId: string): void {
this._authenticatedDao.authenticateUser(username, password).then((authenticatedUser) => {
}).catch(rejected => {
});
}
}
import {createServer, Server} from 'http';
import * as express from 'express';
import * as socketIo from 'socket.io';
import {LogincredentialsDto} from "./models/dto/logincredentials.dto";
import {config} from './config/config';
import AuthenticationService from "./services/implementation/authentication.service";
import {Logger} from "./helperclasses/logger";
import {format} from "util";
export class ClassA {
private readonly _configPort = config.socketServerPort;
private readonly _logger: Logger = Logger.Instance;
private _app: express.Application;
private _server: Server;
private _io: socketIo.Server;
private _socketServerPort: string | number;
private _authenticationService: AuthenticationService;
constructor() {
this.configure();
this.socketListener();
}
private configure(): void {
this._app = express();
//this._server = createServer(config.sslCredentials, this._app);
this._server = createServer(this._app);
this._socketServerPort = process.env.PORT || this._configPort;
this._io = socketIo(this._server);
this._server.listen(this._socketServerPort, () => {
this._logger.log(format('Server is running on port: %s', this._socketServerPort));
});
this._authenticationService = new AuthenticationService(this._io);
}
private socketListener(): void {
this._io.on('connection', (client) => {
client.on('authenticate', (loginCreds: LogincredentialsDto) => {
console.log(loginCreds.username, loginCreds.password, client.id);
this._authenticationService.authenticateUser(loginCreds.username, loginCreds.password, client.id);
});
}
);
}
}
I am trying to mock the function "authenticateUser" in "AuthenticationService", instead of calling the normal code I want to mock the promise. I tried using the examples provided in https://jestjs.io/docs/en/es6-class-mocks but when I try doing the following:
import AuthenticationService from '../src/services/implementation/authentication.service';
jest.mock('./services/implementation/authentication.service');
beforeEach(() => {
AuthenticationService.mockClear();
});
it('test', () => {
// mock.instances is available with automatic mocks:
const authServerInstance = AuthenticationService.mock.instances[0];
I get this error: Error:(62, 31) TS2339: Property 'mock' does not exist on type 'typeof AuthenticationService'.
What am I doing wrong here? Should I be mocking the class/function differently since it's using promises?
To mock an imported function with Jest we use the jest. mock() function. jest. mock() is called with one required argument - the import path of the module we're mocking.
Jest supports TypeScript, via Babel. First, make sure you followed the instructions on using Babel above. Next, install the @babel/preset-typescript : npm.
To mock an exported const in Jest, we can use the jest. mock method. For instance, we write: const mockTrue = { ENABLED: true }; const mockFalse = { ENABLED: false }; describe('allowThrough', () => { beforeEach(() => { jest.
To spy on an exported function in jest, you need to import all named exports and provide that object to the jest. spyOn function. That would look like this: import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.
The typing for AuthenticationService
does not include the mock
property so TypeScript throws an error.
jest.mock
creates an automatic mock of the module which "replaces the ES6 class with a mock constructor, and replaces all of its methods with mock functions that always return undefined
".
In this case the default
export of authentication.service.ts
is an ES6 class so it is replaced with a mock constructor.
The mock constructor has a mock
property but TypeScript doesn't know about it and is still treating AuthenticationService
as the original type.
Use jest.Mocked
to let TypeScript know about the typing changes caused by jest.mock
:
import * as original from './services/implementation/authentication.service'; // import module
jest.mock('./services/implementation/authentication.service');
const mocked = original as jest.Mocked<typeof original>; // Let TypeScript know mocked is an auto-mock of the module
const AuthenticationService = mocked.default; // AuthenticationService has correct TypeScript typing
beforeEach(() => {
AuthenticationService.mockClear();
});
it('test', () => {
// mock.instances is available with automatic mocks:
const authServerInstance = AuthenticationService.mock.instances[0];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With