前言
在前端开发中,我们常常需要对一些外部依赖进行模拟,比如一些接口请求或者第三方库的逻辑。为了解决这个问题,我们经常会使用 Jest 来进行单元测试,并使用其提供的 mock 功能进行模拟。但是,当我们需要模拟一个子模块中的函数时,会遇到一些问题。在本篇文章中,我们将会介绍如何使用 Jest 来 mock 掉一个子模块中的函数。
示例
我们假设有以下代码结构:
// foo.js import { bar } from './bar'; export function foo() { return bar(); } // bar.js export function bar() { return 'original'; }
其中,foo.js
中的 foo
函数引用了 bar.js
中的 bar
函数。现在我们的目标是对 bar
函数进行模拟。
使用 jest.mock
Jest 提供了 jest.mock
方法来进行模拟。我们可以在 foo.test.js
中使用它来对 bar.js
进行模拟:
// foo.test.js import { foo } from './foo'; jest.mock('./bar', () => ({ bar: jest.fn(() => 'mocked'), })); describe('foo', () => { it('should return mocked', () => { const result = foo(); expect(result).toBe('mocked'); }); });
在 jest.mock
方法中,我们传入了一个模拟对象,其中包含了对 bar
函数的模拟。我们使用 jest.fn
来创建一个空的 mock 函数并将其赋给 bar
函数,进而控制其返回值为 'mocked'
。
接下来,我们在测试中调用 foo
函数并检查其返回值是否为 'mocked'
。
使用 jest.requireActual
在某些情况下,我们需要保留子模块的原始实现并仅对其中的部分函数进行模拟。为了实现这个目标,我们可以使用 jest.requireActual
方法来加载子模块的原始实现。
// foo.test.js import { foo } from './foo'; import * as barModule from './bar'; jest.mock('./bar', () => ({ ...jest.requireActual('./bar'), bar: jest.fn(() => 'mocked'), })); describe('foo', () => { it('should return mocked', () => { const result = foo(); expect(result).toBe('mocked'); }); });
首先,我们使用 import * as barModule from './bar'
来加载 bar
子模块。接着,我们在 jest.mock
方法中使用 ...jest.requireActual('./bar')
来加载子模块的原始实现,再通过 bar: jest.fn(() => 'mocked')
来重新实现 bar
函数并使其返回值为 'mocked'
。
使用 jest.doMock
如果我们需要在测试中动态地模拟子模块函数的行为,可以使用 jest.doMock
方法。它和 jest.mock
方法的用法类似,但是可以在运行时动态地进行模拟。
// foo.test.js import { foo } from './foo'; import * as barModule from './bar'; describe('foo', () => { it('should return mocked', () => { jest.doMock('./bar', () => ({ ...barModule, bar: jest.fn(() => 'mocked'), })); const result = foo(); expect(result).toBe('mocked'); }); it('should return original', () => { jest.doMock('./bar', () => ({ ...barModule, bar: jest.fn(() => 'mocked'), })); jest.resetModules(); const { foo } = require('./foo'); const result = foo(); expect(result).toBe('original'); }); });
在第一个测试中,我们使用 jest.doMock
方法动态地模拟了 bar
函数的行为并检查其返回值是否为 'mocked'
。
而在第二个测试中,我们在 jest.resetModules
方法的帮助下重载了 foo.js
和 bar.js
子模块。这样一来,我们就能够得到原始实现中的 bar
函数并检查其返回值是否为 'original'
。
总结
在本篇文章中,我们介绍了如何使用 Jest 来 mock 掉一个子模块中的函数。我们使用了 Jest 提供的 jest.mock
,jest.requireActual
,和 jest.doMock
方法,并展示了它们的使用场景和示例。通过本文的学习,希望读者们能够更好地理解 Jest 的使用技巧,并能够灵活地运用到实际的项目中去。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a12d4badd4f0e0ff94c70c