Bird
Raised Fist0
Vueframework~10 mins

Mocking composables and stores in Vue - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Mocking composables and stores
Start Test Setup
↓
Import composable/store
↓
Mock composable/store
↓
Use mock in test
↓
Run test assertions
↓
Test ends
This flow shows how to replace real composables or stores with mocks during testing to control behavior and verify outcomes.
Execution Sample
Vue
import { ref } from 'vue'
import { useCounter } from '@/composables/counter'
vi.mock('@/composables/counter', () => ({
  useCounter: () => ({ count: ref(10), increment: vi.fn() })
}))

const { count, increment } = useCounter()
This code mocks the useCounter composable to return a fixed count and a mock increment function for testing.
Execution Table
StepActionEvaluationResult
1Import useCounter composableuseCounter is real composableuseCounter function imported
2Mock useCounter with vi.mockMock replaces originaluseCounter now returns count=10 and mock increment
3Call useCounter()Calls mocked versionReturns count=10 (ref) and increment mock function
4Access count.valuecount is ref(10)Value is 10
5Call increment()Calls mock functionNo real increment logic runs
6Test assertions runCheck count and increment callsPass or fail based on mock behavior
💡 Test ends after assertions; mocks isolate composable behavior for controlled testing.
Variable Tracker
VariableStartAfter Step 3After Step 4After Step 5Final
countundefinedref(10)ref(10)ref(10)ref(10)
incrementundefinedmock functionmock functionmock function calledmock function called
Key Moments - 3 Insights
Why does count.value stay 10 even after calling increment()?
Because increment is a mock function with no real logic, count.value does not change. See execution_table step 5.
How does mocking affect the original composable?
Mocking replaces the original composable during tests, so calls use the mock version, not the real one. See execution_table step 2.
What is the purpose of using ref(10) in the mock?
Using ref(10) simulates reactive state so tests can access count.value like in real composable. See execution_table step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of count after step 4?
Aref(10)
Bref(0)
Cundefined
Dmock function
💡 Hint
Check the 'Result' column at step 4 in the execution_table.
At which step does the mock replace the original composable?
AStep 3
BStep 1
CStep 2
DStep 5
💡 Hint
Look at the 'Action' column describing mocking in the execution_table.
If increment was not mocked, what would happen when calling increment() at step 5?
Aincrement would be undefined
Bcount.value would increase
Ccount.value would stay 10
DTest would fail immediately
💡 Hint
Compare behavior of mock vs real composable in the key_moments section.
Concept Snapshot
Mocking composables and stores in Vue tests:
- Use vi.mock() to replace composables/stores
- Provide mock implementations returning refs or mock functions
- Calls to composables use mocks during tests
- Allows controlled state and behavior
- Helps isolate and test components reliably
Full Transcript
This visual execution shows how to mock Vue composables and stores during testing. First, the real composable is imported. Then vi.mock replaces it with a mock version returning fixed reactive state and mock functions. When the composable is called, the mock version runs, returning controlled values. Accessing reactive refs like count.value shows the mocked value. Calling mocked functions like increment does not run real logic but tracks calls. This isolation helps tests focus on component behavior without depending on real composable logic. The variable tracker shows count and increment states across steps. Key moments clarify why count.value stays fixed and how mocking replaces the original composable. The quiz tests understanding of mock effects and state changes. This approach is essential for reliable unit testing in Vue projects.

Practice

(1/5)
1. What is the main reason to mock composables or stores in Vue component tests?
easy
A. To automatically generate UI snapshots
B. To improve the component's runtime performance
C. To isolate the component test from real logic and external dependencies
D. To enable two-way data binding in tests

Solution

  1. Step 1: Understand the purpose of mocking

    Mocking replaces real implementations with fake ones to isolate tests from external logic.
  2. Step 2: Apply this to composables and stores

    Mocking composables and stores prevents side effects and focuses tests on the component itself.
  3. Final Answer:

    To isolate the component test from real logic and external dependencies -> Option C
  4. Quick Check:

    Mocking isolates tests = A [OK]
Hint: Mock to isolate component logic from external code [OK]
Common Mistakes:
  • Thinking mocking improves runtime performance
  • Confusing mocking with UI snapshot generation
  • Believing mocking enables data binding
2. Which syntax correctly mocks a composable module named useAuth using Vitest's vi.mock()?
easy
A. vi.mock('./useAuth', () => ({ useAuth: () => ({ isLoggedIn: true }) }))
B. vi.mock('useAuth', () => ({ isLoggedIn: true }))
C. vi.mock('useAuth', () => ({ useAuth: () => ({ isLoggedIn: true }) }))
D. vi.mock('./useAuth', () => ({ isLoggedIn: true }))

Solution

  1. Step 1: Identify the module path

    Modules are mocked by their relative or absolute path, so './useAuth' is correct if the file is local.
  2. 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.
  3. Final Answer:

    vi.mock('./useAuth', () => ({ useAuth: () => ({ isLoggedIn: true }) })) -> Option A
  4. Quick Check:

    Correct path and factory function = C [OK]
Hint: Mock with correct path and return a function for composables [OK]
Common Mistakes:
  • Using module name without path when path is required
  • Returning state object directly instead of a function
  • Mocking without a factory function
3. Given this mocked store code snippet:
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?
medium
A. undefined
B. 5
C. Error: increment is not a function
D. 0

Solution

  1. Step 1: Analyze the mocked store return values

    The mocked useStore returns an object with count: 5 and increment as a mock function.
  2. Step 2: Check the console.log output

    The count property is 5 and is not changed by calling increment() because it's a mock function without implementation.
  3. Final Answer:

    5 -> Option B
  4. Quick Check:

    Mocked count value logged = 5 [OK]
Hint: Mocked state stays same unless mock function changes it [OK]
Common Mistakes:
  • Assuming mock function changes state automatically
  • Expecting undefined because increment is mocked
  • Confusing mock function with real implementation
4. Identify the error in this test mocking a composable:
vi.mock('./useCounter', () => ({
  useCounter: {
    count: 0,
    increment: vi.fn()
  }
}))
medium
A. The mock should return a function, not an object directly
B. The vi.fn() should be replaced with a real function
C. The module path './useCounter' is incorrect
D. The mock should not include the increment function

Solution

  1. Step 1: Understand composable mocking pattern

    Composable modules export functions, so mocks must return a function, not an object.
  2. Step 2: Identify the incorrect mock structure

    The code returns an object directly instead of a function returning the object.
  3. Final Answer:

    The mock should return a function, not an object directly -> Option A
  4. Quick Check:

    Composable mocks return functions = D [OK]
Hint: Mock composables as functions returning objects [OK]
Common Mistakes:
  • Returning object directly instead of function
  • Replacing vi.fn() unnecessarily
  • Incorrect module path assumptions
5. You want to test a Vue component that uses a Pinia store with a fetchData action. How do you mock the store to verify fetchData is called without running its real logic?
hard
A. Replace fetchData with an empty async function in the real store
B. Import the real store and spy on fetchData without mocking
C. Mock the component instead of the store
D. Use vi.mock() to replace the store module with a mock where fetchData is a vi.fn()

Solution

  1. Step 1: Understand mocking for store actions

    To isolate tests, replace the store module with a mock that has fetchData as a mock function.
  2. Step 2: Use vi.mock() to replace the store module

    This allows you to track calls to fetchData without executing its real code.
  3. Final Answer:

    Use vi.mock() to replace the store module with a mock where fetchData is a vi.fn() -> Option D
  4. Quick Check:

    Mock store action with vi.fn() = A [OK]
Hint: Mock store actions with vi.fn() to track calls without side effects [OK]
Common Mistakes:
  • Not mocking the store and calling real logic
  • Mocking the component instead of the store
  • Replacing functions with empty but untracked implementations
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard