TypeScriptクラス内のインポートされたクラスをモックするためにjestを使用しようとしていますが、メインプログラムには次のコードが使用されています(関数内からいくつかのコードを削除しましたが、何をしようとしているのかは明確です)
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);
});
}
);
}
}
Promiseをモックしたい通常のコードを呼び出す代わりに、「AuthenticationService」の関数「authenticateUser」をモックしようとしています。 https://jestjs.io/docs/en/es6-class-mocks で提供されている例を使用してみましたが、次のことを試してみました。
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];
このエラーが発生します:エラー:(62、31)TS2339:プロパティ 'モック'はタイプ 'typeofAuthenticationService'に存在しません。
私はここで何が間違っているのですか? promiseを使用しているので、クラス/関数を別の方法でモックする必要がありますか?
AuthenticationService
の入力にはmock
プロパティが含まれていないため、TypeScriptはエラーをスローします。
jest.mock
は、モジュールの 自動モック を作成します。これは、「ES6クラスをモックコンストラクターに置き換え、そのすべてのメソッドを、常にundefined
を返すモック関数に置き換えます」。
この場合、authentication.service.ts
のdefault
エクスポートはES6クラスであるため、モックコンストラクターに置き換えられます。
モックコンストラクターにはmock
プロパティがありますが、TypeScriptはそれを認識せず、AuthenticationService
を元のタイプとして処理しています。
jest.Mocked
を使用して、jest.mock
によって引き起こされた入力の変更についてTypeScriptに通知します。
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];