svelte-testing-library
svelte-testing-library copied to clipboard
Any way to wait for exceptions / promise rejections after a fireEvent.Click()?
I'm writing tests using msw and trying to deal with asynchronous click handlers -- but it's nearly impossible for me to get the tests to wait around long enough to catch exceptions or promise rejections.
My hunch is that because fireEvent is async (because it wants svelte to move forward a tick and process the updates), an async callback gets detached from the promise chain so you can't do a simple await.
Here's an example:
Test.svelte
<script>
export let component;
async function handleClick() {
const data = await fetch("https://example.com/api/1/");
throw new Error("Something went wrong!");
}
</script>
<button on:click={handleClick} />
Test.spec.js
import '@testing-library/jest-dom'
import { within } from '@testing-library/dom'
import { render, fireEvent, waitFor, act } from '@testing-library/svelte'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import Test from "./Test.svelte"
// Setup the mock network server
const server = setupServer();
beforeAll(() => {
// Establish requests interception layer before all tests.
server.listen()
})
afterAll(() => {
// Clean up after all tests are done, preventing this
// interception layer from affecting irrelevant tests.
server.close()
})
test('does not work', async () => {
server.use(
rest.get('https://example.com/api/1/', (req, res, ctx) => {
return res(ctx.json({foo: 'bar'}))
})
)
const { findByRole } = render(Test)
const button = await findByRole('button')
expect(await fireEvent.click(button)).toThrow() // fireEvent resolves and succeeds, it's the underlying handler that throws so this doesn't work
})

Understandably, the test finishes before the network call finishes and the test passes (even if there exceptions on the page) -- because the test isn't able to wait for the handler to finish.