用玩笑嘲笑导入的打字稿中的类

dev*_*ran 2 testing unit-testing typescript jestjs

我正在尝试使用开玩笑来模拟Typescript类中的导入类,以下代码用于主程序(我从函数内部删除了一些代码,但仍应清楚我要做什么)

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);
                });
            }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图在“ AuthenticationService”中模拟函数“ authenticateUser”,而不是调用普通的代码来模拟promise。我尝试使用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];
Run Code Online (Sandbox Code Playgroud)

我收到此错误:错误:(62,31)TS2339:类型“ AuthenticationService”的类型不存在属性“模拟”。

我在这里做错了什么?由于使用了promises,我是否应该以不同的方式嘲笑类/函数?

Bri*_*ams 10

问题

的键入AuthenticationService不包含该mock属性,因此TypeScript会引发错误。


细节

jest.mock创建模块的自动模拟,该模块“用模拟构造函数替换ES6类,并将其所有方法替换为总是返回的模拟函数undefined”。

在这种情况下,default导出的authentication.service.ts是ES6类,因此将其替换为模拟构造函数。

模拟构造函数具有一个mock属性,但是TypeScript不知道该属性,并且仍将其AuthenticationService视为原始类型。


使用jest.Mocked让打字稿了解打字变化所造成的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];
Run Code Online (Sandbox Code Playgroud)

  • 这实际上对我不起作用,因为 TypeScript 告诉我我需要先将它转换为 unknown 。ie `original as unknown as jest.Mocked&lt;typeof original&gt;` 有没有人知道解决这个问题的方法? (3认同)
  • @ brian-lives-outdoors我尝试了这个,但是由于某种原因,打字稿仍然将嘲笑的实例视为它在嘲笑的实际类型...有什么想法吗?(尝试模拟接口) (2认同)