Dou*_*ish 2 javascript unit-testing webpack jestjs
我已经尝试寻找这个问题的答案有一段时间了,但我失败了。所以我决定在这里试一试。如果已经有这样的问题而我错过了,我很抱歉重复。
假设我有这个 javascript 模块“myValidator.js”,其中有两个函数,一个函数调用另一个函数。
export const validate = (value) => {
if (!value.something) {
return false
}
// other tests like that
return true
}
export const processValue = (value) => {
if (!validate(value)) {
return null
}
// do some stuff with value and return something
}
Run Code Online (Sandbox Code Playgroud)
像这样测试这个。我想测试验证功能,是否行为正确。然后我有 processValue 函数,它调用第一个函数并在验证正常或为空时返回一些值。
import * as myValidator from './myValidator'
describe('myValidator', () => {
describe('validate', () => {
it('should return false when something not defined', () => {
...
}
}
describe('processValue', () => {
it('should return something when value is valid', () => {
const validateMock = jest.spyOn(myValidator, 'validate')
validateMock.mockImplementation(() => true)
expect(validate('something')).toEqual('somethingProcessed')
}
it('should return null when validation fails', () => {
const validateMock = jest.spyOn(myValidator, 'validate')
validateMock.mockImplementation(() => false)
expect(validate('somethingElse')).toEqual(null)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,问题是这实际上并不像processValue()实际调用模块内部的函数那样工作,因为我认为是闭包。所以这个函数没有被模拟,因为只有导出中的引用被更改为 jest mock,我猜。
我找到了一个解决方案,并在模块内部使用
if (!exports.validate(value))
Run Code Online (Sandbox Code Playgroud)
这适用于测试。然而,我们使用 Webpack (v4) 来构建应用程序,因此它将这些导出转换为自己的结构,然后当应用程序启动时,exports未定义并且代码失败。
测试这个的最佳解决方案是什么?
当然,我可以通过提供一些有效和无效的值来做到这一点,对于这个可行的简单案例,但是我认为应该单独测试它。
或者最好不要模拟函数并通过调用它来避免我遇到的问题,或者有什么方法可以用 JavaScript 模块实现这一点?
我终于找到了这个问题的答案。它实际上在GitHub 上的Jest 示例项目中。
// Copyright 2004-present Facebook. All Rights Reserved.
/**
* This file illustrates how to do a partial mock where a subset
* of a module's exports have been mocked and the rest
* keep their actual implementation.
*/
import defaultExport, {apple, strawberry} from '../fruit';
jest.mock('../fruit', () => {
const originalModule = jest.requireActual('../fruit');
const mockedModule = jest.genMockFromModule('../fruit');
//Mock the default export and named export 'apple'.
return {
...mockedModule,
...originalModule,
apple: 'mocked apple',
default: jest.fn(() => 'mocked fruit'),
};
});
it('does a partial mock', () => {
const defaultExportResult = defaultExport();
expect(defaultExportResult).toBe('mocked fruit');
expect(defaultExport).toHaveBeenCalled();
expect(apple).toBe('mocked apple');
expect(strawberry()).toBe('strawberry');
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1664 次 |
| 最近记录: |