test-utils
test-utils copied to clipboard
Clearing state before/after each test
I am writing a few tests that are changing some internal useState variables of a composable.
However, I noticed that the state of that composable is kept between tests.
This breaks a primary principle of unit testing:
- tests should be isolated.
- tests should work in any order they are run (dependent on 1.)
Even applying
beforeEach(() => {
clearNuxtState();
}
the composable still keeps the state.
You can try the code below as a workaround:
mockNuxtImport('useState', () => {
return <T>(_key: string, data: () => T) => {
return ref(data);
};
});
Tried @p4trykJ solution,
Composables
mockNuxtImport('useState', () => {
return <T>(_key: string, data: () => T) => {
return ref(data);
};
});
export const useMyComposable = () => {
const data = useState<SomeInterface | null>(() => null);
const handleUpdate = async () => {
const response = await fetchSomething();
if(response.result.success) data.value = response.result.data;
// else do nothing (not reset the state intentionally)
}
return {
test,
handleUpdate,
}
}
Unit Test
it('should fetch data successfully', async () => {
const mockResponse = {
result: {
success: true,
data: "dummy",
},
};
// set mock of fetchSomething with mockResponse
await handleUpdate(),
expect(test.value).toEqual(mockResponse);
});
it('should fetch data successfully', async () => {
const mockResponse = {
result: {
success: false,
data: null,
},
};
// set mock of fetchSomething with mockResponse
await handleUpdate();
expect(test.value).toEqual(null); // expected null, received "$a8choa83" (some dummy string)
});
The first test case is passed, but the second one seems to return the state key.
I reommend to mock your state with mockNuxtImport using a mockUserStateFn = vi.fn function hoisted and use on the beforeEach, mockUserStateFn.mockReset() or mockUserStateFn.mockClear().
const { mockUserStateFn } = vi.hoisted(() => {
const mockUserStateFn = vi.fn();
return { mockUserStateFn }
});
mockNuxtImport('useState', () => mockUserStateFn);
beforeEach(() => {
mockUserStateFn.mockReset();
})
@danielroe is this related to #1367?
How do you properly clear useState state between tests in Nuxt/Vitest? Getting state pollution between tests.
How do you properly clear useState state between tests in Nuxt/Vitest? Getting state pollution between tests.
You can do it to the beforeEach using mockUserStateFn.mockClear(); as the mockUserStateFn is the replacement of the implementation of the useState function. You can change the value or implementation for a specific test