Reputation: 17332
This is a simple test using a mocked function. But I do get an ts error for the mock call Object is possibly 'undefined'.ts(2532)
. I don't see how to get rid of this error. This is the structure of the call object, so I think I handle it correctly... but obviously not as expected by ts.
import { render, fireEvent } from '@testing-library/react'
const mockSetCheckbox = jest.fn(() => Promise.resolve())
test('should select checkbox', () => {
// ...
userEvent.click(checkbox)
expect(mockSetCheckbox.mock.calls[0][0].variables.input.checkbox).toBe(true)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Object is possibly 'undefined'.ts(2532)
})
Upvotes: 2
Views: 5036
Reputation: 32158
I'd suggest you to change your test to use .toHaveBeenCalled()
test("should select checkbox", () => {
userEvent.click(checkbox)
expect(mockSetCheckbox).toHaveBeenCalledWith(
expect.objectContaining({
variables: expect.objectContaining({
input: expect.objectContaining({
checkbox: true,
}),
}),
})
);
});
which would assert the same, but you'll get much more understandable error if the implementation changes in a way that the function isn't called.
When using .toHaveBeenCalled()
will look like this:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: ObjectContaining {"variables": ObjectContaining {"input": ObjectContaining {"checkbox": true}}}
Number of calls: 0
Upvotes: 2
Reputation: 1783
It's saying mockSetCheckbox.mock.calls[0][0]
is possibly undefined
, because you're potentially doing mockSetCheckbox.mock.undefined.variables
and you cant reference undefined
like that.
It's trying to help you because your type for whatever calls[0][0]
is is undefined
and/or something else.
Simplest fix is to just assure the checker that it's not going to be undefined
by checking first. Shortcuts exist to do this more concisely if you don't want a buncha if
s.
if(mockSetCheckbox.mock.calls[0][0]) {
expect(mockSetCheckbox.mock.calls[0][0].variables.input.checkbox).toBe(true)
}
You might also want to make sure that your test fails if it is undefined
by throw
ing. The above will silently fail since no expect
s means 'pass'. I prefer to do both by catching the problem and assuming all's well after looking for problems.
Something like:
if(mockSetCheckbox.mock.calls[0][0] === undefined) {
throw "oh no!";
}
expect(mockSetCheckbox.mock.calls[0][0].variables.input.checkbox).toBe(true)
Other options include:
expect(mockSetCheckbox.mock.!calls[0][0].variables.checkbox).toBe(true);
// or
expect((mockSetCheckbox.mock.calls[0][0] as Something).variables.input.checkbox).toBe(true);
// or
let val:Something = mockSetCheckbox.mock.calls[0][0];
expect(val.variables.input.checkbox).toBe(true);
... where Something
is whatever type that contains that variables
object (or any
).
Upvotes: 1