
NativeScript (NS) is a framework for building native applications using JS/TS. If we combine NS with Vue we can build native high-performance applications and also, due to the incredible architecture of NS, NS-Vue and Vue, we can use Vue dependencies as if it were a frontend application. In this case we focus on unit testing with Vitest, a testing framework that is gaining more traction every day, created by the Vue team but made to be able to test almost all the frameworks that we use together with its older brother Vite.
Setup
The first thing to do is install the necessary dependencies for the tests.
npm i -D @types/node@22.9.1 @vitejs/plugin-vue @vue/test-utils vitest jsdom
Now that we have the dependencies, we start with the code. Before starting with the configuration ofvitest
we will create two files that we will use to configure the tests.
To start, for this sample we will create thetest
folder in the root directory of the project in which we will add our tests and files for the general configuration. Inside this folder we create the fileNSMockViews.ts
which will contain an array of the views offered by NativeScript. If you have any views of a plugin you can add it to this list. We will use this file in the vitest configuration.
// test/NSMockViews.tsexportconstNSMockViews=['AbsoluteLayout','ActionBar','ActionItem','ActivityIndicator','Button','ContentView','DatePicker','DockLayout','FlexboxLayout','FormattedString','Frame','GridLayout','HtmlView','Image','Label','ListPicker','ListView','NavigationButton','Page','Placeholder','Progress','ProxyViewContainer','RootLayout','ScrollView','SearchBar','SegmentedBar','SegmentedBarItem','Slider','Span','StackLayout','Switch','TabView','TabViewItem','TextField','TextView','TimePicker','WebView','WrapLayout','Prop','Template',];
Now we will create thesetup.ts
file inside the test folder. In this file we mocknativescript-vue
with@vue/test-utils
and we will also mock@nativescript/core
.
// test/setup.tsimportVuefrom'@vue/test-utils';import{vi}from'vitest';/* MOCK Vue & Nativescript */vi.mock('nativescript-vue',()=>Vue);vi.mock('@nativescript/core',async()=>{return{default:()=>({}),TouchManager:{},};});
So that TypeScript doesn't complain in our tests, we'll add the test folder totsconfig.json
in theinclude
section.
// tsconfig.json"include": [ "src", "types",+ "test"],
With all the base configuration for our tests, we create thevitest.config.mts
file that vitest will use to launch our tests.
// vitest.config.mtsimportVuefrom'@vitejs/plugin-vue';importpathfrom'path';import{defineConfig}from'vitest/config';import{NSMockViews}from'./test/NSMockViews';exportdefaultdefineConfig({plugins:[Vue({template:{compilerOptions:{isCustomElement:(tag)=>NSMockViews.map((nsView)=>nsView.toLowerCase()).includes(tag.toLowerCase()),},},}),],resolve:{alias:{'@':path.resolve(__dirname,'./src'),'~':path.resolve(__dirname,'./src'),},extensions:['.mjs','.js','.ts','.json','.vue'],},test:{globals:true,name:'jsdom',environment:'jsdom',setupFiles:['test/setup.ts'],},});
We briefly explain what we have configured here:
- We use NSMockViews to tell vue that NativeScript components are customElements.
- We added the default NativeScript-Vue aliases so that it resolves the components of our application.
- We indicate the base configuration of the tests.
Build test and run
We now have everything configured. Let's continue creating a basic component that will show an icon to do the tests later on this component.
// src/components/Icon.vue<scriptlang="ts"setup>constprops=defineProps({icon:String});</script><template><Label:text="props.icon"class="m-icon-round"></Label></template>
Let's take action, let's do our first test. We create the filetest/components/icon.test.ts
and add some basic tests, such as checking that the component receives a prop and the NSLabel
view has the text that we are passing to the component.
// test/components/icon.test.tsimportIconfrom'@/components/Icon.vue';import{mount,VueWrapper}from'@vue/test-utils';import{beforeEach,describe,expect,test}from'vitest';letwrapper:VueWrapper<any,any>;beforeEach(async()=>{wrapper=mount(Icon,{props:{icon:'my-icon',},});});describe('Icon Component',async()=>{test('mount component',async()=>{expect(wrapper.html()).toBeTruthy();});test('should have icon as text',async()=>{expect(wrapper.attributes('text')).toContain('my-icon');});test('should update icon',async()=>{expect(wrapper.attributes('text')).toContain('my-icon');awaitwrapper.setProps({icon:'updated-icon'});expect(wrapper.attributes('text')).toContain('updated-icon');});});
We already have our first test. Let's add the script to launch vitest in ourpackage.json
file.
"scripts":{"test":"vitest"},
We are ready to launch the tests, now you just have to launch the tests and you should have 3 tests passing.
npm run test
And that's it! We only had to make a couple of mocks and define the NativeScript views as customElemts.
Here I leave a repository with a base project ready to launch the tests with vitest:https://github.com/vallemar/nativescript-vue-vitest
Happy Testing!
Top comments(1)

- LocationNairobi, Kenya.
- WorkFrontEnd Engineer
- Joined
This is fantastic! Thank you for sharing this amazing article 🔥.
For further actions, you may consider blocking this person and/orreporting abuse