Vue Component Unit Testing with Vitest
This challenge focuses on building robust Vue.js applications by implementing comprehensive unit tests for a given Vue component. Writing unit tests is crucial for ensuring component functionality, preventing regressions, and facilitating confident refactoring. You will use Vitest, a modern and fast testing framework, to test a simple Vue component.
Problem Description
You are tasked with writing unit tests for a UserProfileCard Vue component. This component displays a user's name and an optional status message. The tests should cover various scenarios to ensure the component behaves as expected under different conditions.
Requirements:
- Component Rendering: Test that the
UserProfileCardcomponent renders correctly with provided props. - Prop Handling:
- Test that the
userNameprop is displayed correctly. - Test that the
statusMessageprop is displayed when provided. - Test that the
statusMessageis not displayed when it's an empty string ornull/undefined.
- Test that the
- Interactivity (Optional but Recommended):
- If the component had a hypothetical button to "Toggle Status", you would test that clicking it updates some internal state or emits an event. (For this specific challenge, we'll focus on rendering and prop handling, but consider this for future expansion).
- Test Framework: Use Vitest for writing and running your unit tests.
- Vue Test Utils: Utilize
@vue/test-utilsfor mounting and interacting with your Vue components in tests.
Expected Behavior:
- When
userNameis provided, it should be visible in the rendered output. - When
statusMessageis provided and not empty, it should be visible. - When
statusMessageis an empty string,null, orundefined, the corresponding area for the status message should not be rendered.
Edge Cases to Consider:
- What happens if
userNameis an empty string? - What happens if
statusMessageis an empty string?
Examples
Let's assume the UserProfileCard component has the following structure:
<script setup lang="ts">
import { computed } from 'vue';
interface Props {
userName: string;
statusMessage?: string | null;
}
const props = defineProps<Props>();
const hasStatus = computed(() => !!props.statusMessage);
</script>
<template>
<div class="user-profile-card">
<h2>{{ props.userName }}</h2>
<p v-if="hasStatus" class="status-message">{{ props.statusMessage }}</p>
</div>
</template>
<style scoped>
.user-profile-card {
border: 1px solid #ccc;
padding: 16px;
border-radius: 8px;
}
.status-message {
color: gray;
font-size: 0.9em;
}
</style>
Example 1:
- Input:
<UserProfileCard userName="Alice" statusMessage="Online" /> - Output:
The rendered component should contain:
- An
<h2>tag with the text "Alice". - A
<p>tag with the classstatus-messageand the text "Online".
- An
- Explanation: Both
userNameandstatusMessageare provided and valid, so both should be displayed.
Example 2:
- Input:
<UserProfileCard userName="Bob" /> - Output:
The rendered component should contain:
- An
<h2>tag with the text "Bob". - No
<p>tag with the classstatus-message.
- An
- Explanation:
userNameis provided, butstatusMessageisundefined(not provided), so only the user name is displayed.
Example 3 (Edge Case):
- Input:
<UserProfileCard userName="Charlie" statusMessage="" /> - Output:
The rendered component should contain:
- An
<h2>tag with the text "Charlie". - No
<p>tag with the classstatus-message.
- An
- Explanation: Although
statusMessageis provided, it's an empty string. The component's logic (v-if="hasStatus") correctly prevents the status message from being rendered in this case.
Constraints
- All tests must pass for the solution to be considered complete.
- Tests should be written in TypeScript.
- You are expected to set up Vitest and
@vue/test-utilsin your project. Assume a standard Vue 3 setup with Vite. - The focus is on correctness and readability of the tests. Performance is secondary but generally good with Vitest.
Notes
- You will need to install Vitest and
@vue/test-utilsas development dependencies. - Consider how to import and mount your
UserProfileCardcomponent within your test files. @vue/test-utilsprovides methods likemount,findAll,find,text(),exists(), etc., which will be very useful.- Think about the different ways to assert that elements are present or absent, and that their content is correct.
- For testing components with
setupsyntax (as in the example above),mountfrom@vue/test-utilsis generally the preferred way to render. - Remember to mock any external dependencies if your component were to have them (though this example is self-contained).