繁体   English   中英

我如何使用玩笑来模拟 class?

[英]How can I mock a class using jest?

我怎样才能模拟一些东西来测试像下面的代码这样的东西。 我试着按照这个官方文档,但仍然不适合我https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter

// 一些文件.ts

export const myPublish = async (event: any, context: any): Promise<any> => {
  const myExportHelper = await ExportHelper.getInstance({
    ...commonProps,
  });

  // just some other stuff
  // just some other stuff

  await myExportHelper.transfer(arg1, arg2);
};

export class ExportHelper {
  constructor(
    private readonly bucket: string,
    private readonly read: AWS.S3,
    private readonly write: AWS.S3
  ) {}

  static async getInstance(props: {
    param1: string;
  }) {
    ...
    ...

    return new ExportHelper(arg1, arg2, arg3);
  };

  async transfer(param1, param2) {
    ...
    ...
    console.log('bla bla bla');
  }
}

// 测试文件.test.ts

import { myPublish, ExportHelper } from '../somefile';

beforeEach(() => {
});

afterEach(() => {
    jest.clearAllMocks();
    jest.resetAllMocks();
});

describe('myTest', () => {
    it('should run successfully', async () => {
        // Arrange
        const eventMock = {
            Records: [
                {
                    ...
                }
            ]
        }

        jest.mock('../somefile');
        const mockActualExportHelper = jest.requireActual('../somefile').ExportHelper;
        
        const mockGetInstanceImpl = () => {};

        // this says cannot read property instances of undefined
        const mockExportHelper = mockActualExportHelper.mock.instances[0]; 
        mockExportHelper.getInstance.mockImplementation(mockGetInstanceImpl);
        mockExportHelper.transfer.mockImplementation(mockGetInstanceImpl);

        // Act
        await myPublish(eventMock, jasmine.any({}));

        // Assert
        expect(ExportHelper.getInstance).toBeCalled();
        expect(ExportHelper.transfer).toBeCalled(); // also not sure if this is valid to use ExportHelper
        
    });
});

伴侣。

我认为您正在寻找的不是模拟。 如果您想监视调用了哪些函数,则需要使用spyOn 在开玩笑,你可以做到以下几点:

jest.spyOn(MyClass, 'myMethod');

你也可以mock实现来替代方法的默认行为,一个通用的例子可以是这样的:

jest.spyOn(MyClass, 'myMethod').mockImplementation(jest.fn());

话虽如此,我将重写测试以监视来自ExportHelper的方法并避免外部调用:

import {ExportHelper, myPublish} from '../app';

beforeEach(() => {
});

afterEach(() => {
    jest.clearAllMocks();
    jest.resetAllMocks();
});

describe('myTest', () => {
    it('should run successfully', async () => {
        // Arrange
        const eventMock = {
            Records: [
                {
                    // ...
                }
            ]
        }


        jest.spyOn(ExportHelper, 'getInstance').mockImplementation(jest.fn());
        jest.spyOn(ExportHelper, 'transfer').mockImplementation(jest.fn());

        // Act
        await myPublish('arg1', 'arg2');

        // Assert
        expect(ExportHelper.getInstance).toBeCalled();
        expect(ExportHelper.transfer).toBeCalled();
    });
});

我刚刚替换了这段代码:

        jest.mock('../somefile');
        const mockActualExportHelper = jest.requireActual('../somefile').ExportHelper;
        
        const mockGetInstanceImpl = () => {};

        // this says cannot read property instances of undefined
        const mockExportHelper = mockActualExportHelper.mock.instances[0]; 
        mockExportHelper.getInstance.mockImplementation(mockGetInstanceImpl);
        mockExportHelper.transfer.mockImplementation(mockGetInstanceImpl);

        jest.spyOn(ExportHelper, 'getInstance').mockImplementation(jest.fn());
        jest.spyOn(ExportHelper, 'transfer').mockImplementation(jest.fn());

因为 jest 会跟踪并观察这些方法中的任何一个调用,然后我们可以使用 jest 的匹配器来测试它们是否都被调用了。 mockImplementation将隔离要进行的任何进一步调用。


在重现您的示例时我注意到的一件事是,当您从getInstance获取实例时, transfer方法未被视为一种方法,因此测试不会通过。 但是我觉得这个题不在scope的题目中。 不知道是否恰好发生在我身上。

祝你一切顺利!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM