首页 > 解决方案 > 如何模拟 nanoid 进行测试?

问题描述

我正在尝试模拟 nanoid 进行测试,但它似乎不起作用。

我的功能

  public async createApp(appDto: ApplicationDto): Promise<string> {
    const appWithToken = { ...appDto, accessToken: nanoid() };
    const application = await this.applicationModel.create(appWithToken);

    return application.id;
  }

我的测试:

  beforeEach(() => {
    mockRepository.create.mockResolvedValueOnce({ id: mockId });
  });

  test("creates application and returns an id", async () => {
    const mockAppDto: ApplicationDto = { email: "123@mock.com" };
    const application = await applicationService.createApplication(mockAppDto);

    expect(mockRepository.create).toHaveBeenCalledWith(mockAppDto); //how do I mock the nanoid here?
    expect(application).toBe(mockId);
  });

所以基本上我正在努力弄清楚如何模拟函数内部生成的 nanoid。

我在文件顶部尝试了以下内容:

jest.mock('nanoid', () => 'mock id');

但是它根本不起作用。

任何帮助,将不胜感激!

标签: javascripttypescriptjestjsmocking

解决方案


您没有正确模拟nanoid模块。它使用命名导出来导出nanoid函数。

使用jest.mock(moduleName, factory, options)是正确的,factory参数是可选的。它将创建一个模拟nanoid函数。

此外,您可以使用mocked函数 fromts-jest/utils来处理 TS 类型。

例如

Example.ts

import { nanoid } from 'nanoid';

export interface ApplicationDto {}

export class Example {
  constructor(private applicationModel) {}

  public async createApp(appDto: ApplicationDto): Promise<string> {
    const appWithToken = { ...appDto, accessToken: nanoid() };
    const application = await this.applicationModel.create(appWithToken);

    return application.id;
  }
}

Example.test.ts

import { nanoid } from 'nanoid';
import { Example, ApplicationDto } from './Example';
import { mocked } from 'ts-jest/utils';

jest.mock('nanoid');

const mnanoid = mocked(nanoid);

describe('67898249', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should pass', async () => {
    mnanoid.mockReturnValueOnce('mock id');
    const mockAppDto: ApplicationDto = { email: '123@mock.com' };
    const mockApplicationModel = { create: jest.fn().mockReturnValueOnce({ id: 1 }) };
    const example = new Example(mockApplicationModel);
    const actual = await example.createApp(mockAppDto);
    expect(actual).toEqual(1);
    expect(mockApplicationModel.create).toBeCalledWith({ email: '123@mock.com', accessToken: 'mock id' });
  });
});

测试结果:

 PASS  examples/67898249/Example.test.ts (9.134 s)
  67898249
    ✓ should pass (4 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 Example.ts |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.1 s

推荐阅读