javascript - 如何使用 jest 在 javascript 中测试抽象函数?
问题描述
我有 2 个 javascript A 和 B 函数定义如下,并通过另一个名为 API 的函数公开,如下所示,我想测试函数 A 以查看它是否正在调用 B。
function A () {
B()
}
function B () {
console.log('B is called')
}
export function API (){
return {
a: A,
b: B
}
}
我尝试测试功能的方式如下,它们不起作用。
import { API } from './actions-beta'
describe('test A', () => {
test('', () => {
const fn = API()
console.log(fn)
const spy = jest.spyOn(fn, 'b')
fn.a()
expect(spy).toHaveBeenCalled()
})
})
解决方案
没有办法测试是否B
调用了代码的编写方式。
细节
jest.spyOn
用 spy 替换对象上的函数属性。
jest.spyOn(fn, 'b')
将用间谍替换b
对象上的属性。fn
fn.a()
直接调用A
的调用B
,它不调用fn.b
,因此永远不会调用间谍。
解决方案
A
需要B
使用可以在测试期间替换为 spy 的对象属性进行调用。
创建间谍时,对象通常是模块。
这就是为什么监视导出函数很容易而监视非导出函数非常困难的原因,这带来了一个重要的点:如果一个函数在同一个模块中调用一个非导出函数,那么它只是一个实现细节在模块外部不可见,并且使用黑盒测试方法不需要对其进行测试。
如果您发现这B
不仅仅是一个实现细节,并且您想窥探或存根其功能,那么最简单的方法(特别是对于此代码,其中导出是一个每次调用时都会创建一个新对象的函数)是移动B
到它的自己的模块:
动作-beta.js
import { B } from './lib';
export function A () {
B()
}
export function API (){
return {
a: A,
b: B
}
}
lib.js
export function B () {
console.log('B is called')
}
考试:
import { API } from './actions-beta'
import * as lib from './lib'; // import the module with B
describe('test A', () => {
test('', () => {
const fn = API()
console.log(fn)
const spy = jest.spyOn(lib, 'B') // spy on B using its module
fn.a()
expect(spy).toHaveBeenCalled() // SUCCESS
})
})
推荐阅读
- pandas - Change NaN to None in Pandas dataframe
- jquery - Form Builder does not support on WordPress
- javascript - Making an element display like it was an another element
- asp.net - Value of type 'Control' cannot be converted to 'CheckBox' in vb.net
- python - Use strings in column_property queries
- heroku - How can I add post body in heroku webhooks?
- python-3.x - 列出所有地面标记作业 Boto3-Python
- python - 如何使 python 脚本作为扩展在 chrome 中运行
- python - 是否可以像 API 系统一样运行 Google Colab
- matplotlib - 两个 figure.Figure 对象在 matplotlib 并排