如何用玩笑部分模拟类型安全函数

问题描述 投票:0回答:1

我有一个打字稿应用程序。我正在使用

jest
来模拟
NestFactory
类的
create
函数。

通常,

create
函数返回一个
INestApplication
,其中包含 20 多个方法/属性。我只对其中一个名为
listen
.

的感兴趣

我想模拟

create
方法来返回一个模拟的
listen
这样我就可以使用那个模拟的
listen
来测试东西。

如果不破坏类型安全,我无法做到这一点。

import { NestFactory } from '@nestjs/core';

// Here is the automatic jest mock
jest.mock('@nestjs/core');

// I get mocked NestFactory here with all the type safety.
const mockedNestFactory = jest.mocked(NestFactory);

test('', () => {
  // This is the mocked listen function I want `create` method to return it so I can use it to test some stuff.
  const mockedListen = jest.fn();

  // Here I try to mock create function's implementation and make it return my mocked listen.
  // Of course I get a type error here because my mocked returned object only contains listen and does not contain other 20+ methods/properties that INestApplication contains
  mockedNestFactory.create.mockResolvedValue({
    listen: mockedListen,
  });
});

作为解决方案,我可以将类型转换为

any
,这将破坏所有类型安全,我必须始终手动检查模拟和实际
NestFactory
API 匹配。所以我不想做。

我如何模拟

create
函数,以便它返回一个模拟的
listen
同时保持它的类型安全?

node.js typescript unit-testing jestjs mocking
1个回答
0
投票

不幸的是,我找不到不需要额外包的简单解决方案。

所以,我最终使用了

jest-mock-extended
它可以从
interface
创建一个模拟对象。

这里是用法

import { INestApplication } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { mock } from 'jest-mock-extended';

const mockedNestApplication = mock<INestApplication>();
jest.mocked(NestFactory).create.mockResolvedValue(mockedNestApplication);

在这里,借助

jest-mock-extended
mock
功能。我根据需要的
interface
,
INestApplication
.

创建了一个模拟对象

通过使用它,我提供了一个

mockResolvedValue
create
的方法。

我可以随心所欲地测试

listen
方法。

expect(mockedNestApplication.listen).toHaveBeenCalledOnce();

这样,

  • 我防止使用
    as any
    as unknown as INestApplication
    。它们会导致脆弱的模拟并且不安全。
  • 无需手动实现接口中的所有属性
© www.soinside.com 2019 - 2024. All rights reserved.