-
Notifications
You must be signed in to change notification settings - Fork 33
-
Is there a best practice or a good way to test code that has setup in a parent layout. For example, I used svelte kit latest sample and then tested a page that was using svelte query provider defined in the parent layout.
import { render, screen } from '@testing-library/svelte';
import '@testing-library/jest-dom/vitest';
import { describe, expect, test } from 'vitest';
import Page from './+page.svelte';
describe('/+page.svelte', () => {
test('should render h1', () => {
render(Page);
expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
});
});
This fails with:
FAIL client src/routes/status/page.svelte.test.ts > /+page.svelte > should render h1
Error: No QueryClient was found in Svelte context. Did you forget to wrap your component with QueryClientProvider?
❯ getQueryClientContext node_modules/@tanstack/svelte-query/dist/context.js:7:15
5| const client = getContext(_contextKey);
6| if (!client) {
7| throw new Error('No QueryClient was found in Svelte context. Did you forget to wrap your component with QueryClientProvider?');
| ^
8| }
I'm also noticing other things like dynamic env's are causing issues too.
Beta Was this translation helpful? Give feedback.
All reactions
@niemyjski this is a very good question! Thanks for taking the time to post it.
I lead a team maintaining a large SvelteKit app that uses svelte-query for its client-side API state management. This is a recommendation from me personally rather than anything "official," but I've found the best1 strategy for component tests is pretty classic Uncle Bob: separate the stuff you want to test away from the framework glue. In practice, this means:
- No component-level tests for
+page.svelte
/+layout.svelte
- No component-level tests for anything that wires into
createQuery
,createMutation
, etc. - No/few component-level tests for components that subscribe to context
- Sometimes, especially if its a conte...
Replies: 1 comment 1 reply
-
@niemyjski this is a very good question! Thanks for taking the time to post it.
I lead a team maintaining a large SvelteKit app that uses svelte-query for its client-side API state management. This is a recommendation from me personally rather than anything "official," but I've found the best1 strategy for component tests is pretty classic Uncle Bob: separate the stuff you want to test away from the framework glue. In practice, this means:
- No component-level tests for
+page.svelte
/+layout.svelte
- No component-level tests for anything that wires into
createQuery
,createMutation
, etc. - No/few component-level tests for components that subscribe to context
- Sometimes, especially if its a context that you wrote, you can inject a context into the test instead of avoiding the test entirely
- Structure these "framework" components so they delegate all interesting work to props-driven components and/or pure functions, and write tests for those units instead of the glue
- Include small Playwright E2E suites to validate proper wire-up of your framework glue
- TypeScript and static analysis are also a great, if incomplete, tools to validate framework wire-up
For a simple, if slightly contrived example, if I wanted to test a user dashboard page's heading, I might write something like:
<!-- dashboard/+page.svelte --> <script> import { createUserQuery } from '$lib/api' import DashboardHeading from './dashboard-heading.svelte' const userQuery = createUserQuery() </script> <DashboardHeading user={$userQuery.data} />
<!-- dashboard/dashboard-heading.svelte --> <script> import type { User } from '$lib/api'; const { user }: { user: User | undefined } = $props(); </script> <h1>Hello {user?.name ?? 'friend'}!</h1>
// dashboard-heading.spec.ts // ... it('renders level 1 heading with user name', () => { render(DashboardHeading, { user: { name: 'Alice' } }) const heading = screen.getByRole('heading', { level: 1, name: /helloalice/iu }) expect(heading).toBeInTheDocument() })
From there, I would also make sure that I had an E2E test for this page that also checked that there was a level-1 heading on the page matching.
I've seen a number of guides online that recommend mocking out SvelteKit imports in your tests, but I definitely recommend your try to minimize or eliminate mocking in component tests. I'm a huge fan of mocking, but I've gone down the mock-heavy-component-tests path with React and RTL, and all it got me was a very brittle test suite that slowed my team down. Instead, I prefer to acknowledge that component tests are, by nature, highly integrated with code outside my control, and then do my best to minimize how many layers get tested in a given component test.
Footnotes
-
"Best" meaning "high test coverage of interesting, product-specific logic while prioritizing development speed." ↩
Beta Was this translation helpful? Give feedback.
All reactions
-
I agree with all of this and it was kind of what I was thinking. I just brought over what sveltekit is doing right out of the box with a new project and it's testing +page. I noticed that errored quickly and there really wasn't any diffinitive pointers (your reply should be in the readme).
Thanks again!
Beta Was this translation helpful? Give feedback.