Reputation: 149
I've been struggling to find a way to do something like this:
// 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 ) ...?
)
})
})
I've looked jest docs' expect
section but it seems to me that I cannot check if string is in a specific array (expect.arrayContaining doesn't satisfy this scenario). Any workaround for this?
Upvotes: 0
Views: 334
Reputation: 2732
You will first need to create a utility function which can search for the item inside an items array:
function isItemInTheItemsArray(itemsArr: Item[], targetItem: Item): boolean {
return Boolean(itemsArr.find((item) => item.id === targetItem.id))
}
Instead of using toHaveBeenCalledWith
, you can extract the argument that the doSomething
mock was called with using .mock.calls[0][0]
(where [0]
is the first call and the second [0]
is the first argument of that call):
const itemArg = doSomething.mock.calls[0][0];
Finally, you can use the result itemArg
variable inside the utility function to verify if it is inside the list and assert it using the .toBeTruthy
matcher:
expect(isItemInTheItemsArray(items, itemArg)).toBeTruthy();
Upvotes: 1