>_ Unit Testing Vue 3 Lifecycle Hooks in Composables with Vitest
Learn how to effectively test Vue 3 composables and lifecycle hooks using the withSetup utility function in Vitest. This guide shows you how to write comprehensive unit tests that ensure your composables work as expected.
Testing Vue 3 Lifecycle Hooks in Composables
As a front-end developer working with Vue 3, I often find myself using composables to encapsulate and reuse logic across multiple components. However, testing the lifecycle hooks within these composables can be challenging. That's where the handy withSetup
utility function comes into play.
Understanding the withSetup Function
import { createApp } from 'vue'
export function withSetup(hook) {
let result
const app = createApp({
setup() {
result = hook()
return () => {}
}
})
app.mount(document.createElement('div'))
return [result, app]
}
The withSetup
function takes a hook parameter, which is the composable function we want to test. It creates a new Vue application instance and runs the composable's setup method within that instance. The result is stored and can be used for assertions in our tests.
Example Usage
import { ref } from 'vue'
import { expect, vi, test } from 'vitest'
import { flushPromises } from '@vue/test-utils'
import { useShowDetails } from '@/composables/showDetails'
import { withSetup } from '../../components/__tests__/utils/withSetup'
// Mocking dependencies...
test('showDetails with popup & no route params', async () => {
const [result, app] = withSetup(useShowDetails)
await flushPromises()
expect(result.isLoading.value).toBe(false)
expect(result.showDetails.value).toMatchInlineSnapshot({ ... })
app.unmount()
})
In this example, we're testing the useShowDetails
composable. After calling withSetup
, we use Vue Test Utils' flushPromises to wait for any pending promises to resolve. Then, we can assert against the composable's reactive state.
Remember to always call app.unmount()
to tear down the Vue instance and avoid memory leaks.