Mocking composables and stores helps you test Vue components without relying on real data or side effects. It makes tests faster and more reliable.
Mocking composables and stores in Vue
import { vi } from 'vitest' import * as composableModule from '@/composables/useExample' vi.mock('@/composables/useExample', () => ({ useExample: () => ({ data: 'mocked data', method: vi.fn() }) }))
Use vi.mock() to replace the real composable or store module with a mock version.
Return the mocked functions or data you want your component to use during tests.
vi.mock('@/stores/userStore', () => ({ useUserStore: () => ({ user: { name: 'Test User' }, login: vi.fn() }) }))
import { ref } from 'vue' vi.mock('@/composables/useFetchData', () => ({ useFetchData: () => ({ data: ref('mocked data'), loading: ref(false) }) }))
This test mocks the useCounter composable to return a fixed count and a mocked increment function. It mounts MyComponent which uses this composable. Then it logs the rendered text and checks how many times increment was called.
import { mount } from '@vue/test-utils' import { vi } from 'vitest' import { ref } from 'vue' import MyComponent from '@/components/MyComponent.vue' // Mock the composable vi.mock('@/composables/useCounter', () => { const count = ref(10) const increment = vi.fn() return { useCounter: () => ({ count, increment }) } }) import { useCounter } from '@/composables/useCounter' // Test const wrapper = mount(MyComponent) console.log(wrapper.text()) // Call increment method useCounter().increment() console.log(useCounter().increment.mock.calls.length)
Always import the mocked composable after calling vi.mock() to ensure the mock is applied.
Use vi.fn() to create mock functions you can track in tests.
Mocking helps keep tests fast and focused on the component, not external logic.
Mock composables and stores to isolate component tests from real logic.
Use vi.mock() to replace modules with fake versions.
Mock functions let you check calls and control behavior in tests.
Practice
Solution
Step 1: Understand the purpose of mocking
Mocking replaces real implementations with fake ones to isolate tests from external logic.Step 2: Apply this to composables and stores
Mocking composables and stores prevents side effects and focuses tests on the component itself.Final Answer:
To isolate the component test from real logic and external dependencies -> Option CQuick Check:
Mocking isolates tests = A [OK]
- Thinking mocking improves runtime performance
- Confusing mocking with UI snapshot generation
- Believing mocking enables data binding
useAuth using Vitest's vi.mock()?Solution
Step 1: Identify the module path
Modules are mocked by their relative or absolute path, so './useAuth' is correct if the file is local.Step 2: Provide a factory returning the mocked composable function
The factory must return an object with the composable function that returns the mocked state.Final Answer:
vi.mock('./useAuth', () => ({ useAuth: () => ({ isLoggedIn: true }) })) -> Option AQuick Check:
Correct path and factory function = C [OK]
- Using module name without path when path is required
- Returning state object directly instead of a function
- Mocking without a factory function
vi.mock('./store', () => ({ useStore: () => ({ count: 5, increment: vi.fn() }) }))
const store = useStore();
store.increment();
console.log(store.count);What will be logged to the console?
Solution
Step 1: Analyze the mocked store return values
The mockeduseStorereturns an object withcount: 5andincrementas a mock function.Step 2: Check the console.log output
Thecountproperty is 5 and is not changed by callingincrement()because it's a mock function without implementation.Final Answer:
5 -> Option BQuick Check:
Mocked count value logged = 5 [OK]
- Assuming mock function changes state automatically
- Expecting undefined because increment is mocked
- Confusing mock function with real implementation
vi.mock('./useCounter', () => ({
useCounter: {
count: 0,
increment: vi.fn()
}
}))Solution
Step 1: Understand composable mocking pattern
Composable modules export functions, so mocks must return a function, not an object.Step 2: Identify the incorrect mock structure
The code returns an object directly instead of a function returning the object.Final Answer:
The mock should return a function, not an object directly -> Option AQuick Check:
Composable mocks return functions = D [OK]
- Returning object directly instead of function
- Replacing vi.fn() unnecessarily
- Incorrect module path assumptions
fetchData action. How do you mock the store to verify fetchData is called without running its real logic?Solution
Step 1: Understand mocking for store actions
To isolate tests, replace the store module with a mock that hasfetchDataas a mock function.Step 2: Use
This allows you to track calls tovi.mock()to replace the store modulefetchDatawithout executing its real code.Final Answer:
Usevi.mock()to replace the store module with a mock wherefetchDatais avi.fn()-> Option DQuick Check:
Mock store action with vi.fn() = A [OK]
- Not mocking the store and calling real logic
- Mocking the component instead of the store
- Replacing functions with empty but untracked implementations
Ready to prove it?
Pass the test and this pattern moves unknown
