typescript 如何用jest部分模拟类型安全函数

mkh04yzy  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(156)

我有一份打字申请表。我使用jest来模拟NestFactory类的create函数。
通常情况下,create函数返回一个INestApplication,其中包含20多个方法/属性。我只是对其中一个名为listen的感兴趣。
我想mock create方法返回一个mocked listen,这样我就可以使用mocked 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,这将破坏所有类型安全性,并且我必须始终手动检查mock和实际NestFactory API匹配。所以我不想做。
如何模拟create函数,使其返回模拟的listen,同时保持类型安全?

yyyllmsg

yyyllmsg1#

不幸的是,我找不到一个简单的解决方案,不需要额外的软件包。
所以,我最终使用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-extendedmock函数。我从所需的interfaceINestApplication创建了一个模拟对象。
通过使用它,我提供了一个mockResolvedValuecreate的方法。
我可以测试listen方法,因为我喜欢。

expect(mockedNestApplication.listen).toHaveBeenCalledOnce();

有了这个

  • 我禁止使用as anyas unknown as INestApplication。它们会导致脆弱的模拟,而不是类型安全。
  • 无需手动实现接口中的所有属性。

相关问题