im trying to write tests with Vitest for my vue3 component
this is my component code:
<script lang="ts" setup>
import { reactive, computed, ref, onMounted } from 'vue'
import { formatSubscribers } from '../../helpers/formatSubscribers'
import { formatDescription } from '../../helpers/formatDescription'
import { formatViews } from '../../helpers/formatViews'
import type {PropType} from 'vue'
import { useHistory } from '../../stores/history'
import type { IVideo } from '@/types/video'
const historyStore = useHistory()
interface State {
readMore: boolean
}
const state = reactive<State>({
readMore: false
})
const props = defineProps({
videoId: { type: String, required: true },
video: { type: Object as PropType<IVideo>, required: true }
})
const embedUrl = computed(
() => `https://www.youtube.com/embed/${props.videoId}?autoplay=1&showinfo=1&mute=0`
)
const channelThumbnailUrl = computed(() => props.video?.channel?.thumbnail?.url)
const formattedSubscriberCount = computed(() => {
const subscriberCount = props.video?.channel?.subscriberCount
return formatSubscribers(subscriberCount) + ' inscritos'
})
const descriptionHtml = computed(() => {
return formatDescription(props.video.description, state.readMore)
})
const readMoreButtonLabel = computed(() => {
return state.readMore ? 'ver menos' : 'ver mais'
})
function toggleReadMore() {
state.readMore = !state.readMore
}
function addVideo() {
const history = historyStore.getHistory
if (history.length === 0 || history[0].id !== props.video.id) {
historyStore.addVideo(props.video)
}
}
const videoPlayer = ref<HTMLIFrameElement | null>(null)
onMounted(() => {
videoPlayer.value?.addEventListener('load', addVideo)
})
</script>
<template>
<div class="video">
<div class="iframe-container">
<iframe
ref="videoPlayer"
:src="embedUrl"
frameborder="0"
allowfullscreen
v-if="video"
></iframe>
</div>
<h1 class="video__name">{{ video.title }}</h1>
<div class="video__channel">
<img :src="channelThumbnailUrl" :alt="video.channel.title" />
<div>
<p>{{ video.channel.title }}</p>
<p>{{ formattedSubscriberCount }}</p>
</div>
</div>
<div class="video__description">
<p>{{ formatViews(video.viewCount) }}</p>
<p v-html="descriptionHtml"></p>
<button @click="toggleReadMore">{{ readMoreButtonLabel }}</button>
</div>
</div>
</template>
<style lang="scss" scoped>
.iframe-container {
position: relative;
overflow: hidden;
width: 100%;
padding-top: 56.25%;
/* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */
iframe {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
}
}
.video {
padding: 64px 0;
@media (min-width: 768px) {
padding: 128px 0;
}
&__name {
margin-top: 14px;
margin-bottom: 14px;
font-size: 20px;
}
&__channel {
display: flex;
gap: 14px;
margin-bottom: 14px;
img {
border-radius: 100%;
width: 40px;
height: 40px;
}
}
&__description {
padding: 14px;
border-radius: 8px;
background-color: #282828;
p:first-of-type {
margin-bottom: 14px;
}
button {
height: 48px;
padding: 8px;
margin-top: 14px;
border: none;
border-radius: 8px;
cursor: pointer;
color: inherit;
background-color: transparent;
background-color: hsla(0, 0%, 100%, 0.08);
border: 1px solid hsl(0, 0%, 18.82%);
text-transform: capitalize;
&:hover {
background-color: hsla(0, 0%, 100%, 0.16);
}
}
}
}
</style>
and this is my test:
import { mount } from '@vue/test-utils'
import { describe, it,expect } from 'vitest'
import VideoPlayer from '@/components/UI/VideoPlayer.vue'
import type { IVideo } from '@/types/video';
import { formatViews } from '@/helpers/formatViews';
const videoMock: IVideo = {
id: 'abc123',
title: 'Test Video',
description: 'This is a test video.',
thumbnail: 'https://example.com/thumbnail.png',
channel: {
id: 'def456',
title: 'Test Channel',
thumbnail: {
url: 'https://example.com/channel_thumbnail.png',
width: 100,
height: 100,
},
subscriberCount: '1000',
},
viewCount: '100',
duration: '1:00',
};
describe('Video', () => {
it('displays the video title', () => {
const wrapper = mount(VideoPlayer, { props: { video: videoMock, videoId: '1' } })
expect(wrapper.find('.video__name').text()).toBe('Test Video')
})
it('displays the channel title and subscriber count', () => {
const wrapper = mount(VideoPlayer, { props: { video: videoMock, videoId: '1' } })
expect(wrapper.find('.video__channel p:first-child').text()).toBe('Test Channel')
expect(wrapper.find('.video__channel p:last-child').text()).toBe('1,000')
})
})
the error that i got:
TypeError: $setup.formatViews is not a function
❯ Proxy._sfc_render src/components/UI/VideoPlayer.vue:81:13
I don't know if I need to mock $setup.formatViews. this is the problem? how do I do it?