Testing
Component testing in SAF applications should use:
- Vue Test Utils for basic tooling
- Vitest with JSDOM for running tests
- MSW for network mocking
@saflib/vue
has these as dependencies, and provides helper methods for gluing everything together.
Shared Test App
Each SPA should have a test-app.ts
at the root of the root of the package. See test-app.ts
for information on setting that up. This handles all the plugins that Vue components expect in order to function properly. Most of this will be taken care of by @saflib/vue
's mountWithPlugins
function, but if your SPA has other needs such as additional plugins, test-app.ts
is the place to do that.
Globals
Within your test's describe
block, you should call stubGlobals()
to set up the globals that Vue components expect, such as ResizeObserver which is a common requirement for Vuetify components.
Network Mocking
In order to test the integration of everything involved in rendering a page, you should
- Mount the async component to test, not the page component
vi.waitFor
a string from the page component to render- Mock all API calls that the component makes in the loader method
Rather than including mock data in the same file, which will often be redundant with other files, tests should import mock data from the package that provides the Tanstack queries, per best practices.
Use setupMockServer
within the describe
block next to setupGlobals
. They both handle setup and teardown for each test.
Element Selection
This is where having strings stored separately really pays off. Instead of hard-coding strings in tests that also exist in the Vue component they test, tests should import the adjacent string objects and use getElementByString
to find the elements by text or attributes. This function takes either a string or an object of string values and uses the best selection method, and also converts i18n strings into regular regexes.
Testing Interactions
While not prohibited, testing interactions through Vue component testing is not recommended. This ups the complexity of the stubs required (needing to handle not only GET methods) and provides marginal value. Better to test important interactions as part of larger user flows in Playwright tests.
If there is interaction code which really ought to be tested at a more focused level, this logic should be pulled out of the component and tested in a unit test. If there are complex network behaviors, use withVueQuery
. If they don't use the network, consider pulling them out and testing them as composables.