Testing Vue Components
To mount a vue components and get access to the setup function along with anything injected in plugins we can use the mountSuspended function.
ts
import { describe, expect, beforeEach, it, test } from "vitest"
import ArkForm from "..."
import Field from "..."
describe("description", () => {
beforeEach(async () => {
await mountSuspended(ArkForm, {
// pass in props
props: { name: formName },
})
})
it("should do something", async () => {
// ctx: after component mounts
})
it("something", async () => {
// or we can access the component api
const wrapper = await mountSuspended(ArkForm, {
props: { name: formName },
})
wrapper.classes()
wrapper.props()
wrapper.exists()
wrapper. // ...
})
it("should handle edge case", async () => {
// test logic 3
})
})We can also pass in slots by rendering our component using the h render function.
ts
import { describe, expect, beforeEach, it, test } from "vitest"
import ArkForm from "..."
import Field from "..."
describe("description", () => {
beforeEach(async () => {
const wrapper = await mountSuspended(ArkForm, {
props: { name: formName },
slots: {
// Mount with a child componment in the slot.
default: h(Field, { name: "hello" }),
namedSlot: // ..
},
// Make sure to expose the nested component within the wrapper context.
global: { components: { Field } },
})
})
})A great way to access component state while testing would be to abstract the component into a composable. Then the test and the template will share the same composable interface.
Here is an example. We mount two slots to the <arkform /> component. Then use the useLoginForm composable to assert state transformations.
ts
describe("description", () => {
beforeEach(async () => {
await mountSuspended(Arkform, {
props: { name: "login" },
slots: {
default: [
h(Field, { name: "email", ark: ["string.email"] }),
h(Field, { name: "password", ark: ["string>=6"] }),
],
},
global: { components: { Field } },
})
})
it("wrong email: fails to login", async () => {
const { submit, formName, state } = useLoginForm()
const { set, input } = $form(formName)
set({
email: "mail.com",
password,
})
const out = await submit()
expect(out.ok).toBe(false)
expect(out.code).toBe(401)
})
})