如何检查Jest手动mock中的默认导出函数


以下用于Jest测试的isomorphic-fetch的手动模拟文件返回预期值:
// __mocks__/isomorphic-fetch.ts
import * as req from "./requestData";
const Fetch = (url: string, options: any): Promise<any> => {
const resultPromise = {
text: () => {
return Promise.resolve(req.generateMockResponseData(url, options.body));
},
};
return Promise.resolve(resultPromise);
};
export default Fetch;

然而,我在尝试检查调用它的参数时遇到了问题,因为fetch上的mock属性未定义。我试过两件事:

首先,我在jest.fn中封装了Fetch函数,如下所示:

const Fetch = jest.fn((url: string, options: any): Promise<any> => {
// implementation is same as above
});
export default Fetch;

现在添加之后

import _fetchMock  from "isomorphic-fetch"
const fetchMock = _fetchMock as jest.Mock<Promise<any>>;

在测试文件中,我可以检查使用提取的调用

fetchMock.mock.calls[0]

但现在由于某种原因,应用程序代码中的fetch在测试期间返回未定义。

我尝试的第二件事是从Fetch中删除jest.fn包装并添加

jest.mock("isomorphic-fetch")

到测试文件。现在,fetch在测试期间返回应用程序代码中的预期值,但fetchMock.mock现在再次未定义。

Jest配置:

// jest.config.js
module.exports = {
"clearMocks": true,
"coverageDirectory": "../coverage",
"resetMocks": true,
"restoreMocks": true,
"rootDir": "./src",
"testEnvironment": "jsdom",
"preset": "ts-jest",
"coveragePathIgnorePatterns": ["Error.ts"],
"testEnvironmentOptions": {
"resources": "usable",
"features": {
"FetchExternalResources": ["script", "iframe"],
"ProcessExternalResources": ["script", "iframe"],
}
}
}

GitHub上有一个完整的例子。

Jest spy和常规模拟函数在相同的实现中可能表现不同的原因是Jest spy可以重置为no-op。

这正是在这个Jest设置中发生的事情:

...
"resetMocks": true,
"restoreMocks": true,
...

restoreMocks选项通常是可取的,它通过将监视的方法重置为原始实现来防止测试交叉污染。

resetMocks通常是不受欢迎的并且实际上是不可用的,它将可重用间谍从__mocks__重置为无操作实现。

TL;DR:resetMocks配置选项和jest.resetAllMocks()破坏了可重用间谍的实现,通常应该避免。如果需要重置特定的间谍,可以使用mockReset方法根据具体情况进行重置。

最新更新