Unit Test Vue Pinia
GitHubOfficialFirst committed by rbgmulmbDistributed by GitHub
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to testing Vue 3 components, composables, and Pinia stores. It emphasizes behavior-first testing, black-box assertions, and the correct application of Vitest and Vue Test Utils. It includes specific patterns for configuring Pinia in test environments, such as using createTestingPinia for state seeding, action stubbing, and spy assertions, ensuring tests remain deterministic and decoupled from internal implementation details.
What it does
- Defines a step-by-step workflow for creating behavior-focused unit tests.
- Provides standardized patterns for Pinia store mocking and state seeding.
- Enforces black-box testing principles to avoid coupling tests to component internals.
- Offers guidance on choosing between shallow and full mounting strategies.
- Standardizes the use of action spies and stubbing in Pinia-integrated tests.
- Provides a framework for reviewing existing test suites for coverage and brittleness.
When to use it
- When writing new unit tests for Vue 3 components, composables, or Pinia stores.
- When updating existing tests to align with modern Vue Test Utils and Vitest patterns.
- When debugging or refactoring tests that are overly coupled to implementation details.
- When needing to mock complex Pinia store dependencies in a component test.
- When performing code reviews of test suites to ensure behavior-oriented assertions.
Advantages
- Promotes deterministic and maintainable test suites.
- Reduces test brittleness by focusing on public inputs and observable outputs.
- Provides clear, reusable patterns for common Pinia testing scenarios.
- Ensures consistent testing practices across the codebase.
- Helps identify missing coverage and implementation-coupled assertions.
Usage examples
- “Create a unit test for a UserProfile component that uses a Pinia store to fetch data.”
- The agent will generate a test file using createTestingPinia, stubbing the store actions, and asserting that the component correctly renders the seeded state.
- “Review this test file for a Vue component and suggest improvements.”
- The agent will analyze the test for implementation-coupled assertions, suggest replacing them with behavior-based assertions, and verify the Pinia setup follows the provided patterns.
- “How do I test a Pinia store action that depends on another store?”
- The agent will provide a pattern using setActivePinia and createTestingPinia to mock the dependent store while testing the target store in isolation.
- “Write a test for a form component that emits a save event.”
- The agent will generate a test that triggers a form submission and asserts the emitted event payload using wrapper.emitted().
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/github/unit-test-vue-pinia/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip unit-test-vue-pinia.zip -d .agents/skills
Documentation by rbgmulmb
unit-test-vue-pinia
Use this skill to create or review unit tests for Vue components, composables, and Pinia stores. Keep tests small, deterministic, and behavior-first.
Workflow
Identify the behavior boundary first: component UI behavior, composable behavior, or store behavior.
Choose the narrowest test style that can prove that behavior.
Set up Pinia with the least powerful option that still covers the scenario.
Drive the test through public inputs such as props, form updates, button clicks, emitted child events, and store APIs.
Assert observable outputs and side effects before considering any instance-level assertion.
Return or review tests with clear behavior-oriented names and note any remaining coverage gaps.
Core Rules
Test one behavior per test.
Assert observable input/output behavior first (rendered text, emitted events, callback calls, store state changes).
Avoid implementation-coupled assertions.
Access
wrapper.vmonly in exceptional cases when there is no reasonable DOM, prop, emit, or store-level assertion.Prefer explicit setup in
beforeEach()and reset mocks every test.Use checked-in reference material in
references/pinia-patterns.mdas the local source of truth for standard Pinia test setups.
Pinia Testing Approach
Use references/pinia-patterns.md first, then fall back to Pinia's testing cookbook when the checked-in examples do not cover the case.
Default pattern for component tests
Use createTestingPinia as a global plugin while mounting.
Prefer createSpy: vi.fn as the default for consistency and easier action-spy assertions.
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
}),
],
},
});By default, actions are stubbed and spied.
Use stubActions: true (default) when the test only needs to verify whether an action was called (or not called).
Accepted minimal Pinia setups
The following are also valid and should not be flagged as incorrect:
createTestingPinia({})when the test does not assert Pinia action spy behavior.createTestingPinia({ initialState: ... })orcreateTestingPinia({ stubActions: ... })withoutcreateSpy, when the test only needs state seeding or action stubbing behavior and does not inspect generated spies.setActivePinia(createTestingPinia(...))in store/composable-focused tests (without mounting a component) when mocking/seeding dependent stores is needed.
Use createSpy: vi.fn when action spy assertions are part of the test intent.
Execute real actions only when needed
Use stubActions: false only when the test must validate the action's real behavior and side effects. Do not switch it on by default for simple "was called" assertions.
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
stubActions: false,
}),
],
},
});Seed store state with initialState
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
initialState: {
counter: { n: 20 },
user: { name: "Leia Organa" },
},
}),
],
},
});Add Pinia plugins through createTestingPinia
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
plugins: [myPiniaPlugin],
}),
],
},
});Getter override pattern for edge cases
const pinia = createTestingPinia({ createSpy: vi.fn });
const store = useCounterStore(pinia);
store.double = 999;
// @ts-expect-error test-only reset of overridden getter
store.double = undefined;Pure store unit tests
Prefer pure store tests with createPinia() when the goal is to validate store state transitions and action behavior without component rendering. Use createTestingPinia() only when you need stubbed dependent stores, seeded test doubles, or action spies.
beforeEach(() => {
setActivePinia(createPinia());
});
it("increments", () => {
const counter = useCounterStore();
counter.increment();
expect(counter.n).toBe(1);
});Vue Test Utils Approach
Follow Vue Test Utils guidance: https://test-utils.vuejs.org/guide/
Mount shallow by default for focused unit tests.
Mount full component trees only when integration behavior is the subject.
Drive behavior through props, user-like interactions, and emitted events.
Prefer
findComponent(...).vm.$emit(...)for child stub events instead of touching parent internals.Use
nextTickonly when updates are async.Assert emitted events and payloads with
wrapper.emitted(...).Access
wrapper.vmonly when no DOM assertion, emitted event assertion, prop assertion, or store-level assertion can express the behavior. Treat it as an exception and keep the assertion narrowly scoped.
Key Testing Snippets
Emit and assert payload:
await wrapper.find("button").trigger("click");
expect(wrapper.emitted("submit")?.[0]?.[0]).toBe("Mango Mission");Update input and assert output:
await wrapper.find("input").setValue("Agent Violet");
await wrapper.find("form").trigger("submit");
expect(wrapper.emitted("save")?.[0]?.[0]).toBe("Agent Violet");Test Writing Workflow
Identify the behavior boundary to test.
Build minimal fixture data (only fields needed by that behavior).
Configure Pinia and required test doubles.
Trigger behavior through public inputs.
Assert public outputs and side effects.
Refactor test names to describe behavior, not implementation.
Constraints and Safety
Do not test private/internal implementation details.
Do not overuse snapshots for dynamic UI behavior.
Do not assert every field in large objects if only one behavior matters.
Keep fake data deterministic; avoid random values.
Do not claim a Pinia setup is wrong when it is one of the accepted minimal setups above.
Do not rewrite working tests toward deeper mounting or real actions unless the behavior under test requires that extra surface area.
Flag missing test coverage, brittle selectors, and implementation-coupled assertions explicitly during review.
Output Contract
For
createorupdate, return the finished test code plus a short note describing the selected Pinia strategy.For
review, return concrete findings first, then missing coverage or brittleness risks.When the safest choice is ambiguous, state the assumption that drove the chosen test setup.
References
references/pinia-patterns.mdPinia testing cookbook: https://pinia.vuejs.org/cookbook/testing.html
Vue Test Utils guide: https://test-utils.vuejs.org/guide/
Files
- ATTRIBUTION.mdAdded by AutoGineer871 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md6.9 KiB
- references/pinia-patterns.md1.8 KiB
Requirements and compatibility
Written for: GitHub Copilot
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- First committed by
rbgmulmb
- Publisher
- GitHub (Official)
- Distributed by
- GitHub
- Source
- github/awesome-copilot · skills/unit-test-vue-pinia · commit 797337f
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- rbgmulmb
AutoGineer is not affiliated with or endorsed by rbgmulmb or GitHub.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download unit-test-vue-pinia.zip