Last active
January 31, 2024 07:47
-
-
Save kudoh/e69e8b1f227f58866264d6a928ca0093 to your computer and use it in GitHub Desktop.
Nuxt3(ofetch) + MSW + Vitest with request assertion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { flushPromises, mount, type VueWrapper } from '@vue/test-utils'; | |
| import { expect } from 'vitest'; | |
| import foo from '~/pages/foo.vue'; | |
| import { getJsonRequests, server } from '~/tests/mocks/server'; | |
| import { HttpResponse, http } from 'msw'; | |
| describe('foo', () => { | |
| let wrapper: VueWrapper; | |
| afterEach(() => { | |
| wrapper.unmount(); | |
| }); | |
| test('get', async () => { | |
| server.use(http.get('/api/foo', () => HttpResponse.json({ hello: 'mock' }, { status: 200 }))); | |
| server.listen(); | |
| wrapper = mount(foo); | |
| await wrapper.get('#foo-button').trigger('click'); | |
| await flushPromises(); | |
| expect(wrapper.get('#label').text()).toBe('mock'); | |
| }); | |
| test('post with request assertion', async () => { | |
| server.use(http.post('/api/foo', () => new HttpResponse())); | |
| server.listen(); | |
| wrapper = mount(foo); | |
| await wrapper.get('#bar-button').trigger('click'); | |
| await flushPromises(); | |
| const [request] = await getJsonRequests('post', '/api/foo'); | |
| expect(request.body).toEqual({ bar: 'ofetch' }); | |
| }); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script setup lang="ts"> | |
| import { createFetch } from 'ofetch'; | |
| const value = ref(''); | |
| const get = async () => { | |
| const fetch = createFetch(); // working on msw!! | |
| // const api = $fetch.create({}) // no mock!! | |
| const resp = await fetch('/api/foo', { method: 'GET' }); | |
| value.value = resp.hello; | |
| }; | |
| const post = async () => { | |
| const fetch = createFetch(); | |
| await fetch('/api/foo', { | |
| method: 'post', body: { | |
| bar: 'ofetch' | |
| } | |
| }); | |
| }; | |
| </script> | |
| <template> | |
| <div> | |
| <button id="foo-button" @click="get">foo</button> | |
| <button id="bar-button" @click="post">bar</button> | |
| <div id="label">{{ value }}</div> | |
| </div> | |
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { setupServer } from 'msw/node'; | |
| import { fail } from 'node:assert'; | |
| const server = setupServer(); | |
| server.events.on('request:start', ({ request }) => { | |
| console.debug('MSW intercepted:', request.method, request.url); | |
| }); | |
| let requests: Record<string, Partial<Pick<Request, 'headers' | 'url' | 'method'>> & { | |
| payload: Promise<string> | |
| }[]> = {}; | |
| function createKey(request: { method?: string, path: string }) { | |
| return `${request.method?.toLowerCase() ?? 'get'} ${request.path}`; | |
| } | |
| server.events.on('request:match', async ({ request }) => { | |
| console.log('request:match', request.method); | |
| const key = createKey({ method: request.method, path: new URL(request.url).pathname }); | |
| const promise = request.text(); | |
| if (requests[key]) { | |
| requests[key].push({ ...request, payload: promise }); | |
| } else { | |
| requests[key] = [{ ...request, payload: promise }]; | |
| } | |
| }); | |
| async function getJsonRequests(method: 'get' | 'post' | 'put' | 'delete', path: string) { | |
| const key = createKey({ method, path }); | |
| if (!requests[key]) { | |
| fail(`no request found: ${key}\n\nhistory: \n${Object.keys(requests).join('\n')}`); | |
| } | |
| const result = []; | |
| for (const request of requests[key]) { | |
| try { | |
| const body = JSON.parse((await request.payload)); | |
| result.push({ ...request, body }); | |
| } catch (e) { | |
| console.error(`cannot parse json: ${key}`); | |
| throw e | |
| } | |
| } | |
| return result; | |
| } | |
| function resetRequests() { | |
| requests = {}; | |
| } | |
| export { server, getJsonRequests, resetRequests }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { resetRequests, server } from './server'; | |
| afterAll(() => { | |
| server.close(); | |
| }); | |
| afterEach(() => { | |
| server.resetHandlers(); | |
| resetRequests(); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { defineVitestConfig } from '@nuxt/test-utils/config' | |
| export default defineVitestConfig({ | |
| test: { | |
| environment: 'nuxt', | |
| globals: true, | |
| setupFiles: ['tests/mocks/setup.ts'] | |
| } | |
| }) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
tested by Nuxt 3.10