1

I'm tring to test a component using svelte testing library.

The component has an input tag, whose value is bound (using bind:) to a state variable, and that state variable dictates the text of a title.

So when you change the value of the input tag, it changes the text in the title.

I set up a unit test with svelte testing library, and use fireEvent to change the value of the input tag, but upon asserting the text in the title, it is not changed. It is as if the input tag value changes, but the svelte component state does not update.

Why does the state not change and the title not update? Is there something extra I have to do to get it to update?

Codesandbox repro (run test cases to see problem): https://codesandbox.io/s/xnxjo

1 Answer 1

4

A couple things:

  1. When you use bind:value on an input component in Svelte, Svelte attaches an input event listener to know when to update the value. Firing a change event will update the value, but will not trigger the event listener. So, use fireEvent.input instead of fireEvent.change.

  2. Just because the event has fired doesn't mean the component state has updated. You can wrap fireEvent with act to ensure the component updates before asserting anything.

Updated test:

it("should write in input (variant)", async () => {
  const app = render(App);
  const input = app.getByLabelText("textbox");

  await act(() => fireEvent.input(input, { target: { value: "test" } }));

  expect(input.value).toBe("test");
  expect(app.container.querySelector("h1").textContent).toBe("test");
});
Sign up to request clarification or add additional context in comments.

3 Comments

thanks, this works! Although I ended up using the userEvent library instead 😛
thanks you saved my two last days. One thing : it wasn't necessary for me to wrap fireEvent (even with my tests that was sending an ajax request). I made the reverse move that @Takin1n1 : we're using $app/env that needs ESM to compile for jest. And we didn't achieve to make ESM/jest work with userEvent.
For me it was about the act(), now also this works for me: await act(() => userEvent.click(screen.getByText('text')));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.