Unit Test OnMounted
My component:
How can I check that fetchCities has been called on mounted hook and initialCities was been set ? I use @nuxt/test-utils
16 Replies
Hi @Yuri. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To test that
fetchCities
is called on the mounted hook and initialCities
is set, you can use @nuxt/test-utils
along with @vue/test-utils
for unit testing your Nuxt component. Here's how you can approach this:
1. First, make sure you have set up your testing environment correctly as described in the Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#setup).
2. Create a test file for your component, for example, YourComponent.nuxt.spec.ts
.
3. Use mountSuspended
from @nuxt/test-utils/runtime
to mount your component in a Nuxt environment.
4. Mock the fetchCities
function and the useLocationStore
.
5. Assert that fetchCities
was called and initialCities
was set.
Here's an example of how your test could look:
This test does the following:
1. It mocks the useLocationStore
and the $api
call to avoid actual API requests during testing.
2. It uses mountSuspended
to mount the component in a Nuxt environment.
3. It waits for the next tick to ensure all promises are resolved.
4. It checks if the $api
method (which is called by fetchCities
) was called.
5. It verifies that initialCities
was set with the mocked data.
Remember to adjust the import paths and component name according to your project structure.
For more details on using @nuxt/test-utils
, you can refer to the Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing).
Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#unit-testing) provides more information on unit testing in Nuxt, including how to set up your testing environment and use the provided utilities.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai on this line: expect(wrapper.vm.useNuxtApp().$api).toHaveBeenCalledWith(
I get error
TypeError: [AsyncFunction api] is not a spy or a call to a spy!
Let me check the knowledge base for you again. One moment! :books:
----------------------
I apologize for the confusion in my previous answer. The error you're encountering is because we haven't properly mocked the
$api
function as a spy. Let's correct this approach using @nuxt/test-utils
.
To properly test your component and mock the Nuxt app instance, we can use the mockNuxtImport
helper provided by @nuxt/test-utils/runtime
. Here's a corrected version of the test:
This approach uses mockNuxtImport
to mock both useNuxtApp
and useLocationStore
. The $api
function is now properly mocked as a spy using vi.fn()
, which allows us to make assertions on its calls.
Key points:
1. We use mockNuxtImport
to mock useNuxtApp
and useLocationStore
.
2. The $api
function is mocked using vi.fn()
, which creates a spy.
3. We use vi.runAllTimers()
to ensure all timers (including debounced functions) are executed.
4. We assert on the mocked mockApi
function instead of trying to access it through wrapper.vm
.
This approach should resolve the "TypeError: [AsyncFunction api] is not a spy or a call to a spy!" error you were encountering.
For more information on mocking imports in Nuxt tests, you can refer to the mockNuxtImport
section in the Nuxt documentation (https://nuxt.com/docs/getting-started/testing#mocknuxtimport).
Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#unit-testing) provides more details on unit testing in Nuxt, including how to use the provided utilities like mockNuxtImport
.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai what is correct variant for mock const response = await nuxtApp.$api<ILocationCitySuggests>(apiPath.location.suggest.city, { params })
Let me check the knowledge base for you again. One moment! :books:
----------------------
To correctly mock the
nuxtApp.$api
call in your Nuxt component test, you can use the mockNuxtImport
helper from @nuxt/test-utils/runtime
. Here's the correct way to mock this specific API call:
This approach does the following:
1. It creates a mock API response that matches the structure of ILocationCitySuggests
.
2. It uses vi.fn().mockResolvedValue()
to create a mock function that resolves with the mock response.
3. It uses mockNuxtImport
to mock the useNuxtApp
composable, which returns an object with the mocked $api
function.
This method allows you to control the response of the API call and make assertions about how it was called.
Remember to adjust the apiPath.location.suggest.city
to match the actual path used in your component.
For more information on mocking Nuxt imports and testing, you can refer to the Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#mocknuxtimport).
Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#unit-testing) provides comprehensive guidance on unit testing in Nuxt, including how to use utilities like mockNuxtImport
for mocking imports and API calls.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai
My current test:
But I receive error:
TypeError: nuxtApp.deferHydration is not a function
❯ Object.setup node_modules/nuxt/dist/app/components/nuxt-root.vue:32:27
30|
31| const IslandRenderer = import.meta.server && componentIslands
32| ? defineAsyncComponent(() => import('./island-renderer').then(r => r.default || r))
| ^
33| : () => null
34|
❯ setup node_modules/@nuxt/test-utils/dist/runtime-utils/index.mjs:107:50
❯ callWithErrorHandling node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:200:19
❯ setupStatefulComponent node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7788:25
❯ setupComponent node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7749:36
Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.
Let me check the knowledge base for you again. One moment! :books:
----------------------
The error you're encountering suggests that there's an issue with the Nuxt runtime environment in your test setup. This is likely because the
mountSuspended
function is trying to set up a full Nuxt environment, including the <NuxtRoot>
component, which expects certain Nuxt-specific functions to be available.
To resolve this issue, we need to ensure that the Nuxt testing environment is properly set up. Here are some steps to try:
1. Make sure you're using the latest version of @nuxt/test-utils
.
2. Ensure that your vitest.config.ts
file is correctly configured for Nuxt testing. It should look something like this:
3. Make sure your test file has the .nuxt.spec.ts
extension or includes the // @vitest-environment nuxt
comment at the top of the file.
4. Try to simplify your test setup. Here's a modified version of your test that might work:
5. If you're still encountering issues, you might need to mock additional Nuxt composables. For example:
6. Ensure that your package.json
has the correct test script and dependencies for Nuxt testing.
If you're still facing issues after trying these steps, it might be helpful to check the Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing) for any recent changes or known issues with the testing setup.
Remember, the Nuxt testing utilities are designed to work with a specific Nuxt environment, so make sure all parts of your testing setup are compatible with your Nuxt version and configuration.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
1
@kapa.ai
Let me check the knowledge base for you again. One moment! :books:
Sorry @Yuri, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
@kapa.ai
My component:
And my test:
But i receive errors:
TypeError: nuxtApp.deferHydration is not a function
Where is a mistake?
Let me check the knowledge base for you again. One moment! :books:
----------------------
The error you're encountering suggests that there's an issue with the Nuxt runtime environment in your test setup. This is likely because the
mountSuspended
function is trying to set up a full Nuxt environment, which expects certain Nuxt-specific functions to be available.
To resolve this issue, we need to ensure that the Nuxt testing environment is properly set up. Here are some steps to try:
1. Make sure your test file has the .nuxt.spec.ts
extension or includes the // @vitest-environment nuxt
comment at the top of the file. This ensures that the Nuxt environment is used for your tests.
2. Ensure that your vitest.config.ts
file is correctly configured for Nuxt testing. It should look something like this:
3. You need to mock all the composables used in your component. Here's an updated version of your test that includes mocks for all the necessary composables:
4. Make sure you're importing vi
from Vitest:
5. Remove the createWrapper
function and directly use mountSuspended
in your test.
6. If you're still encountering issues, you might need to mock additional Nuxt composables or globals. For example:
If you're still facing issues after trying these steps, it might be helpful to check the Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing) for any recent changes or known issues with the testing setup.
Remember, the Nuxt testing utilities are designed to work with a specific Nuxt environment, so make sure all parts of your testing setup are compatible with your Nuxt version and configuration.
Nuxt Testing documentation (https://nuxt.com/docs/getting-started/testing#unit-testing) provides comprehensive guidance on unit testing in Nuxt, including how to set up your testing environment and use the provided utilities.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@740173469404364872> Kapa.ai is still learning and improving, please let me know how I did by reacting below.