Vuejs testing library - how to write a test to handle axios request in "mounted" hook
I have a vue component that fetches data from an api in the "created" function. I'm just getting up and running using the following testing stack:
"devDependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/vue": "^5.8.2",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^27.4.6",
"jest": "^27.4.7",
"vue-jest": "^3.0.7",
"webpack-dev-server": "^3.11.0"
}
My current test:
import BatchCalendar from '../src/components/batch_calendar.vue';
import { render } from '@testing-library/vue';
test('It renders correctly and loads initial data', done => {
const wrapper = await render(BatchCalendar);
getByText('Calendar Notices');
});
I know that vue testing library abstracts some methods away from the core vue testing utilities, so I'm left with using the "render" method of vue testing library.
My question is how should I go about handling the API call in the vue created hook.
- Should all api calls (and also async methods?) be mocked?
- How/where do I place await/async functions?
- If I have a plugin (fullcalendar) that is making API requests on its own when rendering, how would I go about mocking/handling that?
Let me know if you need more info, thanks.
do you know?
how many words do you know
See also questions close to this topic
-
How can I get toast-ui editor content?
I am a student studying. I think I'm doing it conceptually wrong.
I'm trying to use vue3 and type script And I'm going to use toast-ui editor.
I get some errors.
- refEditor.value.invoke is not a function
How can I get toast-ui editor content?
this is my code
<template> <div class="markup-tables flex"> <va-card :title="$t('tables.stripedHoverable')"> <va-card-content> <div id="refEditor" ref="refEditor"></div> <br /> <div class="row justify--end paginationButtons-left"> <va-button class="mr-2 mb-2">List</va-button> </div> <div class="row justify--end paginationButtons-right"> <va-button class="mr-2 mb-2" @click="getHTML">Save</va-button> </div> </va-card-content> </va-card> </div> </template> <script lang="ts"> import '@toast-ui/editor/dist/toastui-editor.css' import Editor from '@toast-ui/editor' import { defineComponent, onMounted, ref } from 'vue' import data from '@/data/tables/markup-table/data.json' export default defineComponent({ name: 'BoardWrite', setup() { const refEditor = ref(null) const getHTML = () => { console.log('getHTML test') let html = refEditor.value.invoke('getHtml') console.log(html) // ERROR } onMounted(() => { const editor = new Editor({ el: refEditor.value, height: '700px', initialEditType: 'markdown', previewStyle: 'vertical', }) editor.getMarkdown() }) return { getHTML, refEditor, } }, }) </script>
-
Deploy VueJS + API app to Azure Static Web App with Gitlab doesn't create functions
I've started creating a small application that will use VueJS as a frontend with Azure Functions as the backend. I was looking at using Azure Static Web Apps to host both components for the application and Gitlab to store / deploy the app.
Everything but the creation of the Azure functions works. Following https://docs.microsoft.com/en-us/azure/static-web-apps/gitlab?tabs=vue
The output from the deploy step, listed below is:
App Directory Location: '/builds/*/valhalla/valhalla-client/dist/spa' was found. Api Directory Location: '/builds/*/valhalla/valhalla-api/dist' was found. Looking for event info Could not get event info. Proceeding Starting to build app with Oryx Azure Static Web Apps utilizes Oryx to build both static applications and Azure Functions. You can find more details on Oryx here: https://github.com/microsoft/Oryx ---Oryx build logs--- Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx You can report issues at https://github.com/Microsoft/Oryx/issues Oryx Version: 0.2.20220131.3, Commit: ec344c058843461525ff03b46031553b6e15a47a, ReleaseTagName: 20220131.3 Build Operation ID: |qAffRWArEg8=.deee9498_ Repository Commit : 7cdd5b61f956e6cb8459b13a42af363c4440a97b Detecting platforms... Could not detect any platform in the source directory. Error: Could not detect the language from repo. ---End of Oryx build logs--- Oryx was unable to determine the build steps. Continuing assuming the assets in this folder are already built. If this is an unexpected behavior please contact support. Finished building app with Oryx Starting to build function app with Oryx ---Oryx build logs--- Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx You can report issues at https://github.com/Microsoft/Oryx/issues Oryx Version: 0.2.20220131.3, Commit: ec344c058843461525ff03b46031553b6e15a47a, ReleaseTagName: 20220131.3 Build Operation ID: |NGXLP5bVBRk=.705477f6_ Repository Commit : 7cdd5b61f956e6cb8459b13a42af363c4440a97b Detecting platforms... Could not detect any platform in the source directory. Error: Could not detect the language from repo. ---End of Oryx build logs--- Oryx was unable to determine the build steps. Continuing assuming the assets in this folder are already built. If this is an unexpected behavior please contact support. [WARNING] The function language could not be detected. The language will be defaulted to node. Function Runtime Information. OS: linux, Functions Runtime: ~3, node version: 12 Finished building function app with Oryx Zipping Api Artifacts Done Zipping Api Artifacts Zipping App Artifacts Done Zipping App Artifacts Uploading build artifacts. Finished Upload. Polling on deployment. Status: InProgress. Time: 0.1762737(s) Status: InProgress. Time: 15.3950401(s) Status: Succeeded. Time: 30.5043965(s) Deployment Complete :) Visit your site at: https://polite-pebble-0dc00000f.1.azurestaticapps.net Thanks for using Azure Static Web Apps! Exiting Cleaning up project directory and file based variables 00:00 Job succeeded
The deploy step appears to have succeeded, and the frontend is deployed, but there are no Azure Functions showing up in this Static Web App. Is something missed here? So far, the Azure Functions I have are the boiler-plate from instantiating a new Azure Function folder.
image: node:latest variables: API_TOKEN: $DEPLOYMENT_TOKEN APP_PATH: '$CI_PROJECT_DIR/valhalla-client/dist/spa' API_PATH: '$CI_PROJECT_DIR/valhalla-api/dist' stages: - install_api - build_api - install_client - build_client - deploy install_api: stage: install_api script: - cd valhalla-api - npm ci artifacts: paths: - valhalla-api/node_modules/ cache: key: node paths: - valhalla-api/node_modules/ only: - master install_client: stage: install_client script: - cd valhalla-client - npm ci artifacts: paths: - valhalla-client/node_modules/ cache: key: node paths: - valhalla-client/node_modules/ only: - master build_api: stage: build_api dependencies: - install_api script: - cd valhalla-api - npm install -g azure-functions-core-tools@3 --unsafe-perm true - npm run build artifacts: paths: - valhalla-api/dist cache: key: build_api paths: - valhalla-api/dist only: - master needs: - job: install_api artifacts: true optional: true build_client: stage: build_client dependencies: - install_client script: - cd valhalla-client - npm i -g @quasar/cli - quasar build artifacts: paths: - valhalla-client/dist/spa cache: key: build_client paths: - valhalla-client/dist/spa only: - master needs: - job: install_client artifacts: true optional: true deploy: stage: deploy dependencies: - build_api - build_client image: registry.gitlab.com/static-web-apps/azure-static-web-apps-deploy script: - echo "App deployed successfully." only: - master
-
How to global import a stylus file in vite
Now I'm try use
vite
to create avue
app. But have trouble to global import astylus
file invite.config.js
.I try the code from vite docs.
export default defineConfig({ css: { preprocessorOptions: { styl: { additionalData: `@import "./src/assets/styles/common.styl"` } } } })
But it's completely not work.
I got a solution to set global style from github.
export default defineConfig({ css: { preprocessorOptions: { stylus: { globals: { '$highlight-color': 'red' } } } } })
It's works fine, But how to import a styl file globaly? I tried to add 'additionalData' to the workable config. However I got bunch of errors: 'failed to locate file'. It seems like try to import the file in every .vue file, but has trouble to locate the file.
css: { preprocessorOptions: { stylus: { additionalData: `@import "./src/assets/styles/common.styl";`, globals: { '$color-g1': '#F3F4FC', '$color-white': '#FFFFFF', } } } }
Have any idea about this?
-
Is there any way to mock API responses using snapshots?
I'm currently trying to find a good way to mock API responses for a subset of end-to-end tests, and was thinking it would be swell if there was a way to take snapshots when the backend services are healthy, and then use those snap-shotted responses in place of making actual HTTP requests when the tests are being run. Does anyone know if a library exists for this sort of thing?
Basically, I'd like to do something like the following:
it('does something', () => { const data = process.env.UPDATE_SNAPSHOTS ? getDataFromServer() : getDataFromSnapshot(); saveSnapshot(data); // Saves snapshot data to file system like jest // Test things using "data" });
It would be great if I could just use jest for this, since I'm using jest anyway. But as far as I can tell, jest doesn't have any file-based snapshot methods besides
toMatchSnapshot()
and I really need to be able tosaveSnapshot()
andreadSnapshot()
arbitrarily. -
Mock 'S3' feature of 'aws-sdk' (nodeJS and Jest)
I need to test a file in charge of retrieving data from S3 through the 'aws-sdk' (nodeJs + Jest). The file is:
const AWS = require('aws-sdk'); let S3 = null; const getS3 = async () => { if (S3 === null) { const config = { endpoint: new AWS.Endpoint(process.env.S3_URL), s3ForcePathStyle: true, }; S3 = new AWS.S3(config); } return S3; }; module.exports.getObjectList = async (prefix) => { const params = { Bucket: process.env.S3_BUCKET, Delimiter: '/', Prefix: prefix, }; const s3 = await getS3(); const objectList = s3 .listObjects(params) .promise() .then((data) => { const keys = data.Contents.map((c) => c.Key); return keys; }) .catch((err) => { console.error(err); return null; }); return objectList; };
and the test file is as below :
const s3Client = require('./s3Client'); const mockS3Instance = { listObjects: jest.fn().mockReturnThis(), promise: jest.fn().mockReturnThis(), catch: jest.fn(), }; jest.mock('aws-sdk', () => { return { S3: jest.fn(() => mockS3Instance), Endpoint: jest.fn(() => { 'blabla'; }), }; }); describe('s3Client tests', () => { it('basic test', async () => { const getObjectListResult = await s3Client.getObjectList('test'); expect(1).toBe(1); }); });
But a error message is returned :
ypeError: s3.listObjects(...).promise(...).then is not a function
-
Unexpected Jest Errors when Mocking Uppy
I'm attempting to mock the
Uppy
class from the uppy package in a Jest unit test following guidance from this previously answered question. My failing code is below:import Uppy from '@uppy/core'; describe('MyComponent', () => { it('renders', () => { jest.mock('@uppy/core', () => { return { Uppy: jest.fn().mockImplementation(() => { return {}; }), }; }); new Uppy(); expect(Uppy).toHaveBeenCalledTimes(1); }); });
The test fails with the following error message:
Matcher error: received value must be a mock or spy function Received has type: function Received has value: [Function Uppy]
It appears that the default export from
@uppy/core
is theUppy
class, so my expectation is that the provided code would mock the class' constructor, however this doesn't seem to be the case.Package versions:
- Uppy: 2.1.2
- Jest: 27.4.7
-
How to test transition function in Vue 3 test utils?
I have a problem testing transiton functions with jest and vue test utlis. This is my component code:
<div class="disclosure"> <button class="label" type="button" @click="toggle" > <span class="label-text"> <slot name="disclosure-title" /> </span> </button> <Transition name="disclosure" @before-enter="transitionBaseState" @enter="transitionEndState" @before-leave="transitionEndState" @leave="transitionBaseState" > <div v-show="open" class="panel" > <div class="panel-content"> <slot /> </div> </div> </Transition> </div>
I have a problem with transition functions: transitionBaseState and transitionEndState. When I run ejst spec for the component, coverage tab shows that those functions are not covered. Do you know what is the best way to test those functions? My test for showing element is this:
it('can be changed to opened by clicking the panel', async () => { await wrapper.find(buttonSelector).trigger('click'); expect(wrapper.find(panelSelector).isVisible()).toBe(true); });
Functions:
function transitionBaseState(el: HTMLElement): void { el.style.height = '0'; } function transitionEndState(el: HTMLElement): void { el.style.height = `${el.scrollHeight}px`; }
-
Adding Props to found components throw the mounted wrapper
I have a form that contains a selector reusable component like this
<template> <div class="channelDetail" data-test="channelDetail"> <div class="row"> <BaseTypography class="label">{{ t('channel.detail.service') }}</BaseTypography> <BaseSelector v-model="serviceId" data-test="serviceInput" class="content" :option="servicePicker.data?.data" :class="serviceIdErrorMessage && 'input-error'" /> </div> <div class="row"> <BaseTypography class="label">{{ t('channel.detail.title') }}</BaseTypography> <BaseInput v-model="title" data-test="titleInput" class="content" :class="titleErrorMessage && 'input-error'" /> </div> </div> </template>
I'm going to test this form by using vue-test-utils and vitest. I need to set option props from the script to the selector. In my thought, this should be worked but not
it('test', async () => { const wrapper=mount(MyForm,{}) wrapper.findComponent(BaseSelector).setProps({option:[...some options]}) ---or wrapper.find('[data-test="serviceInput"]').setProps({option:[...some options]}) ---or ??? });
Could anyone help me to set the props into components in the mounted wrapper component?
-
Testing call to other functions within the same component using nuxt.js and jest
I'm trying to write a test that tests the various method calls to other methods within the same file. So far, I've written tests for two different methods, one passes, one does not.
async updateOnDeleteImage() { try { this.getAllAvailableImages() let result = await SliderService.getSlideInformation(this.currentSlide) this.slideData = result } catch (error) { console.error(error) } finally { this.autoUnpublishOnChange() this.refreshPreviewBox() } }
and here is the test file thus far:
import { shallowMount, createLocalVue } from '@vue/test-utils' import ControlsBoxRight from '@/components/pages/slider-manager/controls-box-right' import Vuetify from 'vuetify' import Vuex from 'vuex' let vuetify describe('Test slider manager controls box', () => { const localVue = createLocalVue() let wrapper localVue.use(Vuex) const currentSlideMock = jest.fn() currentSlideMock.mockReturnValue(1) const store = new Vuex.Store({ getters: { getSelectedSlide: currentSlideMock } }) beforeEach(() => { vuetify = new Vuetify() }) test('updateOnDeleteImage calls getAllAvailableImages', async () => { wrapper = shallowMount(ControlsBoxRight, { localVue, store, propsData: { slideId: 1 }, }) wrapper.vm.getAllAvailableImages = jest.fn() wrapper.vm.updateOnDeleteImage() wrapper.vm.$nextTick() expect(wrapper.vm.getAllAvailableImages.mock.calls.length).toBe(1) }) test('updateOnDeleteImage calls get autoUnpublishOnChange', async () => { wrapper = shallowMount(ControlsBoxRight, { localVue, store, propsData: { slideId: 1 }, }) wrapper.vm.autoUnpublishOnChange = jest.fn() wrapper.vm.updateOnDeleteImage() wrapper.vm.$nextTick() expect(wrapper.vm.autoUnpublishOnChange.mock.calls.length).toBe(1) }) })
the test for getAllAvailableImages passes, the autoUnpublishOnChange test does not, both are within the same file. I'm not sure why the second isn't passing.
Additionally, the way Nuxt structures the file system allows me to create service files that make the actual api calls, and I then import those service files to access the api calls. I'm having trouble figuring out how to mock a call to a service file.
I ask both questions because they both happen within the updateOnDeleteImage method
-
Testing child components in Vue 3 with Vitest and Testing Library
I am implementing a small Vue3 app that guides the user through several steps by clicking next/previous button. I want to add tests that verify that the correct view/component is showing up after clicking on next/previous button.
- There is no vue-router
- I am using a Pinia store
At the moment I am using Vitest, vue-testing-libary and jest-dom to write the tests. I'm not sure if it is possible to accomplish my issue with these tools. If possible I don't want to use vue-test-utils because vue-testing-libary is build on top of it and seems to be the newer solution. Maybe I need to use Cypress?
<template> <div v-if="store.myCondition.length > 0"> <FirstView v-if="store.step === 1"/> <SecondView v-if="store.step === 2"/> <ThirdView v-if="store.step === 3"/> </div> <div v-else>Loading ...</div> </template>
Here is a dummy test that does nothing but printing the rendered HTML. In the rendered HTML there is no view rendered at all.
test('debug test', () => { screen.debug() })
-
vue 2 jest coverage is incorrect
I have setup unit testing using installation instructions from https://v1.test-utils.vuejs.org/
Tests are running properly. But the coverage is coming incorrectly.
In the report it is showing it has only 1 statement, 1 function, 2 branches for some reason.
It's not showing coverage for all the lines. It shows coverage in the first line and doesn't show coverage anywhere else. Don't know what's the issue is here.
I'm using Bootstrap-vue to render components. Can this create an issue with coverage? I'm asking this because the example.spec.js that came for the helloworld component is showing coverage correctly.
my dev dependencies
"devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-unit-jest": "^5.0.4", "@vue/cli-service": "~5.0.0", "@vue/test-utils": "^1.3.0", "@vue/vue2-jest": "^27.0.0-alpha.2", "babel-jest": "^27.0.6", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "flush-promises": "^1.0.2", "jest": "^27.0.5", "node-sass": "^7.0.1", "sass-loader": "^12.6.0", "vue-template-compiler": "^2.6.14" },