Vue3의 Typesafe mockable globals
16016 단어 vuetypescript
이것을 어떻게 달성합니까?
내 애플리케이션의 이름이 'Peer'라고 가정해 보겠습니다. 몇 가지 유용한 전역 변수를 포함할 인터페이스를 정의하는 것으로 시작하겠습니다. 특히 날짜 형식 지정 및 일부 콘솔 작업에 사용할 수 있는 문자열1:
PeerGlobals.ts
export interface PeerGlobals {
log: (m: string) => void
logError: (m: string) => void
defaultDateFormat: string
}
그런 다음 플러그인에서 구현하고 제공합니다.
PeerPlugin.ts
import { App, Plugin } from 'vue'
import { PeerGlobals } from 'PeerGlobals'
export const PeerPlugin: Plugin {
install(app: App) {
const globals: PeerGlobals = {
log: console.log,
logError: console.error,
defaultDateFormat: 'yyyy-MM-dd',
}
app.provide('globals', globals)
}
}
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { PeerPlugin } from './PeerPlugin'
const app = createApp(App)
// use any other plugin here like Router or Pinia
app.use(PeerPlugin)
app.mount('#app')
이제 모든 구성 요소에서 다음을 수행할 수 있습니다.
MyComponent.vue
<script lang="ts" setup>
import type { PeerGlobals } from '@/PeerGlobals'
const globals = inject('globals') as PeerGlobals
</script>
테스트에 관해서는 파일
mockPeerGlobals.ts
을 만들어 이 전역 변수에 의존하는 구성 요소를 마운트하는 모든 테스트에서 사용할 수 있습니다.mockPeerGlobals.ts
import type { PeerGlobals } from '@/PeerGlobals'
export const mockPeerGlobals: PeerGlobals = {
log: () => {},
logError: () => {},
defaultDateFormat: 'yyyy-MM-dd',
}
MyComponent.spec.ts
import { mount } from '@vue/test-utils'
import { mockPeerGlobals } from 'mockPeerGlobals'
import MyComponent from '@/components/MyComponent.vue'
function mountMyComponent() {
return mount(MyComponent, {
global: {
provide: {
globals: mockPeerGlobals
}
}
})
}
// ...tests
전역 함수에 대한 어설션
mockPeerGlobals.ts
에서 로그 함수는 빈 스텁이지만 일반적으로 모의 함수로 대체하여 예상대로 호출되었음을 확인할 수 있습니다(예: jest에서 jest.fn()
사용 또는 vitest에서 vi.fn()
사용) . 테스트를 실행하기 전에 모든 모의 객체를 올바르게 재설정해야 합니다.창 및 문서 사용
경우에 따라
window
및 document
에 액세스해야 하는데 일반적으로 테스트 환경에서는 사용할 수 없습니다. 따라서 이를 전역 인터페이스 뒤에 두는 것도 유용합니다. 그러나 이러한 개체에는 엄청난 양의 속성이 포함되어 있으므로 이를 조롱하는 것은 너무 많은 작업이 될 것입니다. 대신 mapped types이라는 타이프 스크립트 마법을 사용하여 모든 속성을 선택적으로 만들 수 있습니다.PeerGlobals.ts
type MockWindow = {
[k in keyof Window]?: Window[k]
}
type MockDocument = {
[k in keyof Document]?: Document[k]
}
export interface PeerGlobals {
window: (Window & typeof globalThis) | MockWindow
document: Document | MockDocument
// ...other globals
}
이제 모의 전역에서 테스트와 관련된 기능만 구현하면 됩니다.
querySelectorAll
가 우리가 사용하는 유일한 것이라고 가정합니다.mockPeerGlobals.ts
import type { PeerGlobals } from '@/PeerGlobals'
export const mockPeerGlobals: PeerGlobals = {
window: {},
document: {
querySelectorAll: () => []
},
// ...other globals
}
테스트별로 모의 구현을 원하면 어떻게 해야 합니까?
mockPeerGlobals.ts
에서 했던 것처럼 모의 개체를 내보내는 것은 다소 제한적입니다. 모든 테스트는 동일한 전역 개체를 사용해야 합니다. 그러나 때로는 테스트별 모의 구현이 필요합니다. 이를 지원하도록 변경mockPeerGlobals.ts
해 보겠습니다. 여기서 Ramda 라이브러리의 도우미 함수를 사용합니다. mergeDeepRight
:mockPeerGlobals.ts
import { mergeDeepRight } from 'ramda'
import type { PeerGlobals } from '@/PeerGlobals'
// ...define default globals
export function getMockPeerGlobals(overrides?: Partial<PeerGlobals>): PeerGlobals {
return mergeDeepRight(mockPeerGlobals, (overrides as any) || {})
}
이제 테스트에서 나머지 전역에 영향을 주지 않고 모든 수준의 중첩에서 모든 속성을 재정의할 수 있습니다.
MyComponent.spec.ts
import { mount } from '@vue/test-utils'
import { mockPeerGlobals } from 'mockPeerGlobals'
import MyComponent from '@/components/MyComponent.vue'
function mountMyComponent() {
return mount(MyComponent, {
global: {
provide: {
globals: getMockPeerGlobals({
document: {
querySelectorAll: () => []
}
// the rest of globals remain unaffected
})
}
}
})
}
// ...tests
콘솔 작업을 인터페이스 뒤에 두는 것은 테스트 출력에 로그가 인쇄되는 것을 방지하는 데 유용합니다. ↩
Reference
이 문제에 관하여(Vue3의 Typesafe mockable globals), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/peerhenry/typesafe-mockable-globals-in-vue3-498a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)