Javascript 笑话:模仿第三方模块
最近,我一直在尝试通过Jest学习单元测试,阅读文档和各种文章 有一件事我还没有弄清楚,那就是: 我试图测试一个nodeJS模块,它有一个Javascript 笑话:模仿第三方模块,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,最近,我一直在尝试通过Jest学习单元测试,阅读文档和各种文章 有一件事我还没有弄清楚,那就是: 我试图测试一个nodeJS模块,它有一个if语句,条件是os.platform() 我的测试是否有办法将os.platform返回值设置/模拟为其他值,这样当Jest运行测试文件时,测试文件将读取测试套件中指定的os.platform()值 PS:foo()无法通过依赖项注入接受平台。foo()的实现是固定的 myModule.js import os from 'os'; export const
if
语句,条件是os.platform()
我的测试是否有办法将os.platform
返回值设置/模拟为其他值,这样当Jest运行测试文件时,测试文件将读取测试套件中指定的os.platform()值
PS:foo()
无法通过依赖项注入接受平台。foo()
的实现是固定的
myModule.js
import os from 'os';
export const foo = () => {
if (os.platform() === `win32`) {
module = module.split(`\\`).join(`\\\\`);
}
}
import * as myModule from '../myModule.js';
// Guessing I need to use spyOn, to test the actual module code?
const myModuleMock = jest.spyOn(myModule, 'foo');
describe('myModule', () => {
it('can run with different os.platform() values', () => {
myModuleMock();
expect(myModuleMock).toHaveBeenCalled();
// How do I specify what value os.platform() in foo() should return?
});
});
myModule.test.js
import os from 'os';
export const foo = () => {
if (os.platform() === `win32`) {
module = module.split(`\\`).join(`\\\\`);
}
}
import * as myModule from '../myModule.js';
// Guessing I need to use spyOn, to test the actual module code?
const myModuleMock = jest.spyOn(myModule, 'foo');
describe('myModule', () => {
it('can run with different os.platform() values', () => {
myModuleMock();
expect(myModuleMock).toHaveBeenCalled();
// How do I specify what value os.platform() in foo() should return?
});
});
您可以通过在
\uuuumocks\uuuu
目录中添加os.js
文件来模拟os
模块:
// ./__mocks__/os.js
const os = jest.requireActual('os')
os.platform = jest.fn().mockReturnValue('testPlatform')
module.exports = os
或者,仅使用一个文件:
const mockOS = jest.requireActual('os')
mockOS.platform = jest.fn().mockReturnValue('testPlatform')
jest.mock('os', () => mockOS)
import os from 'os'
test('os', () => {
expect(os.platform()).toBe('testPlatform')
})
因此,您的测试文件应该如下所示:
const mockOS = jest.requireActual('os')
mockOS.platform = jest.fn().mockReturnValue('testPlatform')
jest.mock('os', () => mockOS)
import * as myModule from '../myModule.js';
describe('myModule', () => {
it('can run with different os.platform() values', () => {
myModuleMock();
expect(myModuleMock).toHaveBeenCalled();
});
});```
您可以将
os
导入到测试文件中,并使用jest.spyOn
对其进行如下模拟:
import * as myModule from '../myModule.js';
import os from 'os';
describe('myModule', () => {
it('can run with different os.platform() values', () => {
const spy = jest.spyOn(os, 'platform');
spy.mockReturnValue('mocked response'); // <= mock the return value
myModule.foo();
expect(spy).toHaveBeenCalled(); // Success!
});
});
jest.mock('os', () => {
const os = jest.requireActual('os');
jest.spyOn(os, 'platform').mockReturnValue('mocked response');
return os;
});
请注意,工厂功能必须是完全独立的。我的建议是学习如何使用摩卡和西农。已经创建了很多文档和示例。我将导入
os
,看看是否可以通过模拟(或存根)函数在if
语句中使用的方法来影响它。尝试更改代码,使其使用聚合或依赖项注入。它将允许您以更简单的方式对其进行单元测试。在本例中,您可以模拟/stubos
,然后将其传递给您的代码。努力让你的最后一个例子起作用。导入必须位于顶部否?require和import都需要吗?因此,如果我在该测试中运行foo(),那么myModule.js中的foo()将读取我在测试中设置的平台值?我将import移到顶部,但得到以下错误:ReferenceError:mockOS未定义
,在jest.mock
中,jest.mock
调用被提升到顶部,但是我建议在import.Hi之前保留它。非常感谢。myModuleMock是否在任何地方定义?哦,你只是错过了我密码中的间谍。我现在就试试你的建议。谢谢布莱恩,这是一个有用的技巧。布莱恩,谢谢。在那里不需要使用间谍,对吗?我只是通过做:jest.mock('os',()=>{return{platform:jest.fn()}})然后,在我的测试中我做了:os.platform.mockReturnValue('customPlatformValue');myModuleMock()代码>。是的,这也很好用。您甚至可以将其简化为jest.mock('os',()=>({platform:jest.fn()}))代码>…只需确保测试期间运行的其他代码不需要os
,因为这将替换os
中的所有代码@马格纳斯