-
Notifications
You must be signed in to change notification settings - Fork 668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Composables are not being mocked in Vitest #2066
Comments
I'm also running into problems with testing composables. Example:
export function useFoo() {
function bar(text: string): void {
baz(text);
}
function baz(text: string): void {
console.log(text);
}
return {
bar,
baz
}
}
describe('bar', () => {
test(`should call baz with 'foobar'`, () => {
// given
const _useFoo = useFoo();
vi.spyOn(_useFoo, 'baz');
// when
_useFoo.bar('foobar');
// then
expect(_useFoo.baz).toHaveBeenCalledWith('foobar')
});
}); Stackblitz: https://stackblitz.com/edit/vitejs-vite-hlmyzy?file=src%2Fcomposables%2F__tests__%2Fuse-foo.spec.ts I've tried multiple variations, the only thing that works if I fully |
@jaysaurus and @maartentibau, have you had any luck with this? I believe I'm having the same problem. |
I don't know yet why but changing vtu version from 2.4.0 to 2.4.1 and Vitest from 0.31.0 to any greater, breaks many tests I have with stores and composables mocked. If I keep 2.4.0 and 0.31.0 together, everything is fine. And I don't know if it is because something has changed about how Vitest manages the mocks or other things related to vtu. |
Finally, I realized that the problem (in some of my tests) was using properties from a composable that is mocked totally. These properties were obtained from the composable using destructuring assignment syntax. In current versions of my package, this error is never shown |
In case it helps, I've managed to successfully mock composables like as per the below. Versions:
I've also found that using the JavaScript Debugger in VS Code to run the tests, often unearths some underlying issues that prevent the mock from successfully being used in tests. Usually it's been due to some other superfluous data that hasn't been mocked, but should be - though I'm mostly looking at higher level components at/near the top of the tree. |
@LaurenceNairne Hi, could you maybe explain how this resolves the issue you demonstrated in your stackblitz? I have the same issue, and could not understand your resolution. |
I had troubles doing it right for a long time too. Thanks to @LaurenceNairne I managed to mock one of my composable (can't say yet if it works everywhere 😅): All my composables are located in a folder (and subfolders) called My component under test is using With the following, I managed to have the right objects
|
This is working for me using vitest (you can switch this code to jest pretty easily): const mockUseSearch = vi.hoisted(() => ({
loading: false,
search: vi.fn(),
searchResults: []
}));
vi.mock("@/ui/composables/search", () => ({
useSearch: () => {
return {
loading: computed(() => mockUseSearch.loading),
search: mockUseSearch.search,
searchResults: computed(() => mockUseSearch.searchResults)
};
}
}));
describe("SearchDialog", () => {
it("should have search dialog", () => {
render(SearchDialog);
expect(screen.getByRole("textbox")).toBeInTheDocument();
expect(screen.getByRole("button")).toBeInTheDocument();
// you could also fire a click event on the button
// and check the "search" spy if you wanted
// fireEvent.click(screen.getByRole("button"));
// expect(mockUseSearch.search).toHaveBeenCalled();
});
it("should show previous results when opened on another page", () => {
mockUseSearch.searchQuery = "Hello world";
mockUseSearch.searchResults = [{}, {}];
render(SearchDialog);
expect(screen.getByText(mockUseSearch.searchQuery)).toBeInTheDocument();
expect(screen.getByRole("list")).toHaveLength(mockUseSearch.searchResults.length);
});
}); |
Any updates here? the above solutions in this thread are not working for me. |
Can you post an example of your code @bdeo? |
Subject of the issue
I have a vue 3 project using
<script setup>
tagsI import a composable into a component on the project.
I attempt to mock the composable in my test.
I observe that the composable is mocked accordingly during debugs of the test however once the debugger jumps to
<script setup>
the composable is observed and is not mockedSteps to reproduce
<script setup>
tag.(note I have tried numerous different variations on this them, with and without vi.fn() )
bazMethod
from useFooComposable, clicks the button and thereafter:expect(bazMethod).toBeCalled()
Expected behaviour
because the useFooComposable mock has switched
bahComputedProperty
to true, the test should fire bazMethod.Actual behaviour
the debugger observes that both
bahComputedProperty
andbazMethod
are mocked in the test script but when the debugger jumps to themyEvent
call in the component, neither the property nor the event have been mocked. This isn't an issue for the contrived event here but handling all permutations of composables makes for extremely fragile tests in production code.Possible Solution
I've tried setting it as a mock and I've tried directly altering
wrapper.vm.bazMethod
after the fact and neither gives me any change.my colleague has had some success with
but this feels obscure given how much demand there is for composables in Vue 3. It simply feels - in the first place - like VTU isn't honouring vi.mock and that it probably should since this is the preferred manner of mocking imports in the given framework.
The text was updated successfully, but these errors were encountered: