I have a Svelte component that imports a function and then provides that function as a click handler in the template. I would like to spyOn and mock this function using jest. After mocking the function, any calls to functions that call the mocked function work as expected, but clicking on the element that uses the function as a handler results in the real function being called and not the mock. A
Here is a codesandbox with the issue https://codesandbox.io/s/crazy-fast-uxgqe?file=/app.test.js
test-util.ts
export const foo = () => console.log('real foo');
export const bar = () => foo();
Test.svelte
<script lang="ts">
import { foo, bar } from '@utils/test-util';
</script>
<button on:click={foo} data-testid="foo">foo</button>
<button on:click={bar} data-testid="bar">bar</button>
import { render } from '@testing-library/svelte';
import Test from '@components/Test.svelte';
import * as testUtil from '@utils/test-util';
import userEvent from '@testing-library/user-event';
test('fails', async () => {
const fooMock = jest
.spyOn(testUtil, 'foo')
.mockImplementation(() => console.log('mock foo'));
const testComponent = render(Test);
await userEvent.click(testComponent.getByTestId('bar')); // logs 'mock foo'
await userEvent.click(testComponent.getByTestId('foo')); // logs 'real foo'
expect(fooMock).toHaveBeenCalledTimes(2); // fails, actual value 1
});
Short of adding an intermediary function like bar just for the sake of testing, how would I approach mocking foo so that the mock is called when used as a handler?