老实说,我对在对我的应用程序进行单元测试时模拟某些函数的目标感到困惑。我看过一些文章建议我应该模拟我测试的所有内容,但也有其他文章建议我应该尽可能避免模拟。
我需要一些帮助来理解是否模拟部分代码背后的决定。
假设我有以下功能:
export const numberFormat = (num) => {
return new Intl.NumberFormat('en-EN', {
style: 'decimal',
maximumFractionDigits: 2
}).format(num)
}
我决定通过导入文字函数来测试它,就像这样:
import { test, expect } from 'vitest'
import { numberFormat } from './numberFormat.js'
const numValue = 1000.12345678
test('number is formatted', () => {
expect(numberFormat(numValue)).toBe('1,000.12')
})
这会是错误的吗?我实际上只是格式化一个数字,为什么我应该嘲笑这个函数?
当我们要计划或定义单元测试时,我们希望将要测试的东西分成原子和非常简单的单元。如果您有
f
功能,那么您可能想知道以下部分:
f
f
正在调用f
的使用方式可能类似如果您想知道
f
的算法,那么您的单元会模拟 f
正在调用的函数,其想法是,好吧,让我们假设这些函数已被执行,并且它们的结果是 this 和 this 和 this。在这种情况下 f
会表现良好吗?因此,在这种情况下,您模拟 f
正在调用的函数,但测试 f
。
另一方面,如果您对
f
正在调用的函数感兴趣,那么您需要区分这些函数的用例并在不模拟它们的情况下测试它们。
最后,如果您对
f
的用法感兴趣,而不是 f
本身,那么您可以模拟 f
并测试其用法,其中包含 f
以某种方式表现以及其用法将如何响应的想法这种情况。
因此,每当您考虑
f
时,问题就是您对特定测试中 f
的哪些方面感兴趣。是否有某个函数 f
正在调用?还是f
本身?或者它的用法?为了决定是否嘲笑f
,你需要回答这些问题。