我一直在努力寻找一种方法来做这样的事情:
// module
const m = {
doSomething: (id: string) => {}
}
type Item = { id: string }
const randomInt = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1) + min)
}
const fn = (items:Item[]) => {
const toBeUsed = items[randomInt(0, items.length - 1)]
m.doSomething(toBeUsed.id)
}
// test
describe("fn", () => {
it("should pick one of items as arg", () => {
// arrange
const items:Item[] = [{ id: 'r1'}, { id: 'r2'}, { id: 'r3'}]
const doSomething = jest.spyOn(m, 'doSomething')
// act
fn(items)
// assert
expect(doSomething).toHaveBeenCalledWith(
// Here, check if arg is one of items.map( i => i.id ) ...?
)
})
})
我已经看过jest docs的expect
节,但在我看来,我无法检查字符串是否在一个特定的数组中(期望)。arraycontains不满足这个场景)。有什么解决办法吗?
首先需要创建一个实用程序函数,它可以在items数组中搜索项目:
function isItemInTheItemsArray(itemsArr: Item[], targetItem: Item): boolean {
return Boolean(itemsArr.find((item) => item.id === targetItem.id))
}
不使用toHaveBeenCalledWith
,您可以提取使用.mock.calls[0][0]
调用doSomething
模拟的参数(其中[0]
是第一个调用,第二个[0]
是该调用的第一个参数):
const itemArg = doSomething.mock.calls[0][0];
最后,您可以在实用程序函数中使用结果itemArg
变量来验证它是否在列表中,并使用.toBeTruthy
匹配器断言它:
expect(isItemInTheItemsArray(items, itemArg)).toBeTruthy();