How could I set a private svelte variable for the unit testing?
E.g. I have the component:
//a.svelte
<script>
let a = "b";
</script>
<div data-testid="c">{a}</div>
And I am trying to test the component:
import { screen } from "@testing-library/svelte";
import a from "./a.svelte;
...
//arrange
const aMock = "d";
//act
render(a);
//assert
expect(screen.getByTestId("c").textContent).toBe("d");
How can I set the a
inside the a.svelte
? I do not want to make the a
a property, i.e. I do not want to do the export let a = "b";
. I want to keep a
as an internal state of the component, but I would like to mock it.
If you compile with the dev
flag, you will get additional functions on the component for capturing and setting component state, e.g. the default REPL with its name
state generates:
$$self.$capture_state = () => ({ name });
$$self.$inject_state = $$props => {
if ('name' in $$props) $$invalidate(0, name = $$props.name);
};
if ($$props && "$$inject" in $$props) {
$$self.$inject_state($$props.$$inject);
}
You can also inject an initial state via $$inject
as part of the props.
Since local state usually cannot be changed from outside, the compiler will not generate any render update code unless the local variable is assigned somewhere. A dummy assignment (a = a
) could be used to ensure that.
Example of both setting a different initial state and updating it later:
<script>
import Component from './Component.svelte';
let c;
let newName = '';
function mount(node) {
c = new Component({
target: node,
props: { $$inject: { name: 'Steve' } },
});
return {
destroy() { c.$destroy(); }
};
}
function changeName() {
c.$inject_state({ name: newName });
}
</script>
<div use:mount />
<input bind:value={newName} />
<button on:click={changeName}>Change</button>