Writing unit tests in #Nuxt can quickly get messy. You start mocking everything, dealing with flaky tests, and wondering "am I even testing this the right way?" 🫠
Over time I came up with some simple practices that keep my tests clean.
Sharing them here, maybe some of these will make your project life easier too ✌️
Mock Nuxt specifics👍
Without this, tests crash. Nuxt has its own injections
Isolate network🌐
Tests should never hit the real API
Use Pinia Testing👩💻
Test stores without a real backend
Put logic into composables📁
Functions are easier to test than components
Stable selectors🫵
Test edge cases🤔
Always check empty data, errors, large values
Control async😎
Keeps your test stable, not flaky
Mock plugins & i18n🎭
Replace t and everything just works
Keep tests small🤏
One test = one idea
Also i do suggest you to keep track of you coverage and make as big as possible👜
Over time I came up with some simple practices that keep my tests clean.
Sharing them here, maybe some of these will make your project life easier too ✌️
Mock Nuxt specifics
vi.mock('#app', () => ({
useRuntimeConfig: () => ({ public: { apiBase: 'http://fake' } }),
useFetch: vi.fn().mockResolvedValue({ data: { message: 'ok' } })
}));Without this, tests crash. Nuxt has its own injections
Isolate network
(useFetch as any).mockResolvedValue({
data: { message: 'Mocked response' },
pending: false,
error: null
});Tests should never hit the real API
Use Pinia Testing
import { createTestingPinia } from '@pinia/testing';
mount(MyComponent, { global: { plugins: [createTestingPinia()] } });Test stores without a real backend
Put logic into composables
// composables/useSum.ts
export const useSum = (a:number,b:number)=>a+b;
// useSum.spec.ts
expect(useSum(2,3)).toBe(5);
Functions are easier to test than components
Stable selectors
<!-- Button.vue -->
<button data-test="submit-btn">Send</button>
expect(wrapper.get('[data-test="submit-btn"]').text()).toBe('Send');data-test is reliable even if CSS classes change.Test edge cases
expect(formatMoney(0)).toBe('$0.00');Always check empty data, errors, large values
Control async
await nextTick();
vi.useFakeTimers();
Keeps your test stable, not flaky
Mock plugins & i18n
vi.mock('vue-i18n', () => ({
useI18n: () => ({ t: (key:string)=>key })
}));Replace t and everything just works
Keep tests small
it('adds todo', ()=>{ store.add('task'); expect(store.items.length).toBe(1); });
it('toggles todo', ()=>{ store.toggle(1); expect(store.items[0].done).toBe(true); });One test = one idea
Also i do suggest you to keep track of you coverage and make as big as possible
Please open Telegram to view this post
VIEW IN TELEGRAM
1