I would expect this test to pass but it fails:
it('should consume files on drop', () => {
const mock = jest.fn();
const file = new File(['file'], 'file.txt', { type: 'text/plain' });
const fileList = [file];
render(<DropZone onDocumentDrop={mock} />);
const dropZone = screen.getByTestId('dropZone');
const dropEvent = createEvent.drop(dropZone);
Object.defineProperty(dropEvent, 'dataTransfer', {
value: {
files: {
item: (index: number) => fileList[index],
length: fileList.length,
},
},
});
fireEvent(dropZone, dropEvent);
expect(dropZone).toBeInTheDocument();
expect(mock).toHaveBeenCalled();
expect(mock).toHaveBeenCalledWith({
item: (index: number) => fileList[index],
length: 1,
});
});
Jest reports that:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
- Expected
+ Received
- {"item": [Function item], "length": 1},
+ {"item": [Function item], "length": 1},
I am not sure how to make it pass or get anymore insight into what is wrong?
Mock functions allow you to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls), capturing instances of constructor functions when instantiated with new , and allowing test-time configuration of return values.
To check if a function was called correctly with Jest we use the expect() function with specific matcher methods to create an assertion. We can use the toHaveBeenCalledWith() matcher method to assert the arguments the mocked function has been called with.
mockFn.mockClear() Often this is useful when you want to clean up a mocks usage data between two assertions.
When checking the arguments of the last function call, you can use expect.objectContaining()
to match the received object.
You can also use lastCalledWith()
instead of toHaveBeenCalledWith()
. They are both the same but I personally prefer the former because it's shorter and easier to read.
const item = (index: number) => []
const args = {
length: 1,
item,
}
const mock = jest.fn()
mock(args)
expect(mock).lastCalledWith(
expect.objectContaining({
length: expect.any(Number), // or 1 if you know the exact value
item: expect.any(Function),
})
)
Two different objects in javascript are not the same value, even if they have the same key/value pairs - An object is stored in memory as a reference and so two different objects have two different references, therefore they are not equal.
Try defining the object once instead and passing it's reference around:
const files = {
item: (index: number) => fileList[index],
length: fileList.length,
};
Object.defineProperty(dropEvent, 'dataTransfer', { value: { files, }, });
// -- snip --- //
expect(mock).toHaveBeenCalledWith(files);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With