使用玩笑模拟时的typescript错误

IT技术 javascript reactjs typescript unit-testing jestjs
2021-04-25 13:27:52

我有一个先前创建的.js文件,它模拟了我们的一些功能以进行jest测试。我正在将其迁移到一个.ts文件:

服务器.ts

const Server = jest.genMockFromModule('../Server');

Server.getAsync = Server.default.getAsync;
// other REST-ful functions here

export default Server;

我收到以下错误:

类型“{}”上不存在属性“getAsync”

类型“{}”上不存在属性“default”

然后,在相应的测试文件中:

MyComponent.test.ts

import Server from 'path/to/Server';

jest.mock('path/to/Server');

const dispatchMock = jest.fn();
const getStateMock = jest.fn();

describe('MyComponent.someFunction', () => {
    beforeEach(() => {
        jest.resetAllMocks();
    });

    it('Does the right stuff', () => {
        Server.getAsync.mockReturnValueOnce(Promise.resolve([{ key: 'value' }]));
        dispatchMock.mockImplementationOnce((promise) => promise);
        dispatchMock.mockImplementationOnce();

        return someFunction()(dispatchMock)
            .then(() => {
                expect(Server.getAsync).toHaveBeenCalledTimes(1);
                expect(Server.getAsync.mock.calls[0][0]).toBe('something');
            });
    });
});

我遇到错误 dispatchMock.mockImplementationOnce()

预期 1 个参数,但得到 0。(方法) jest.MockInstance<{}>.mockImplementationOnce(fn: (...args: any[]) => any): jest.Mock<{}>

...在 Server.getAsync.mockReturnValueOnce

属性 'mockReturnValueOnce' 在类型 '(url: string, baseRoute?: string | null, loadingGenerator?: (isLoading: boolean) => { type: strin...' 上不存在。

...等等 Server.getAsync.mock

属性 'mock' 在类型 '(url: string, baseRoute?: string | null, loadingGenerator?: (isLoading: boolean) => { type: strin...' 上不存在。

我一直在努力解决这个问题,所以任何帮助都将不胜感激。

更新

好的,我添加as anyServer.ts文件第一行的末尾,现在看起来像:

const Server = jest.genMockFromModule('../Server') as any;

这消除了第一组错误。尽管如此,仍然面临我的.test.ts文件中的错误

更新 2

我注意到,当我运行实际的 jest 测试时,即使存在 TypeErrors,它们也都通过了。这些问题似乎与实际测试无关。

4个回答

我自己解决了这个问题。我让它工作的方式是将任何调用转换Server.getAsync为特定的 jest 模拟类型。

let getAsyncMock = Server.getAsync as jest.Mock

或者

let getAsyncMock = <jest.Mock>(Server.getAsync)

这摆脱了我的错误。

在@nobleare 响应之后……一个很好的更新是将您的模拟实现包装到 中beforeAll并将其清除到beforeEach块中:

import { AnalyticsApi } from "../../api/src";

jest.mock("../../api/src");

describe('...', () => {

  beforeAll(() => {
    (AnalyticsApi as jest.Mock<AnalyticsApi>).mockImplementation(() => ({
      listPolicies: jest.fn().mockResolvedValue('promiseValue')
    }));
  });

  beforeEach(() => {
    (AnalyticsApi as jest.Mock<AnalyticsApi>).mockClear();
  });

});

使用这个

import { mocked } from 'ts-jest/utils';
import { foo } from './foo';
jest.mock('./foo');


expect(mocked(foo)).toHaveLength(1);

要覆盖导入,您可以这样做:

import { AnalyticsApi } from "../../api/src";

jest.mock("../../api/src");

let listPolicies = jest.fn(() => {
  return Promise.resolve();
});

(AnalyticsApi as jest.Mock<AnalyticsApi>).mockImplementation(() => ({
  listPolicies,
}));