콘텐츠로 이동

TestIntent는 Intent 디스크립터의 구성을 검사해요: 어떤 Command를 참조하고 어떤 실행 모드를 사용하는지. “이 Intent가 디스패치되면 Store가 무엇을 실행하는가?”라는 질문에 답해요.

import { TestIntent } from '@hurum/core/testing'
import { PurchaseIntents } from './intents'
const intent = TestIntent(PurchaseIntents.submitClicked)

TestIntentIntents() 정의에서 가져온 Intent 디스크립터를 받아 commandsmode가 있는 읽기 전용 객체를 반환해요.

Intent가 실행할 Command 목록이에요:

const intent = TestIntent(PurchaseIntents.submitClicked)
expect(intent.commands).toEqual([ValidateCommand, SavePurchaseCommand])

Intent가 올바른 Command에 연결되었는지 검증해요. Intent를 리팩터링해서 Command를 추가하거나 제거하면, 이 테스트가 변경을 잡아내요.

실행 모드 — Command가 어떻게 실행되는지:

// Sequential (default): commands run one after another
const sequential = TestIntent(PurchaseIntents.submitClicked)
expect(sequential.mode).toBe('sequential')
// All (fail-fast parallel): commands run concurrently, abort all on first failure
const failFast = TestIntent(PurchaseIntents.loadAll)
expect(failFast.mode).toBe('all')
// AllSettled (independent parallel): commands run concurrently, all complete independently
const independent = TestIntent(PurchaseIntents.initialize)
expect(independent.mode).toBe('allSettled')
모드생성 방법동작
sequentialIntent(cmd1, cmd2)Command를 순서대로 실행
allIntent.all(cmd1, cmd2)동시 실행, 첫 에러 시 전체 중단
allSettledIntent.allSettled(cmd1, cmd2)동시 실행, 모두 독립적으로 완료
intents.test.ts
import { describe, it, expect } from 'vitest'
import { TestIntent } from '@hurum/core/testing'
import { PurchaseIntents } from './intents'
import {
ValidateCommand,
SavePurchaseCommand,
LoadPricesCommand,
LoadInventoryCommand,
} from './executors'
describe('PurchaseIntents', () => {
it('submitClicked runs validation then save', () => {
const intent = TestIntent(PurchaseIntents.submitClicked)
expect(intent.commands).toEqual([ValidateCommand, SavePurchaseCommand])
expect(intent.mode).toBe('sequential')
})
it('initialize loads prices and inventory concurrently', () => {
const intent = TestIntent(PurchaseIntents.initialize)
expect(intent.commands).toEqual([LoadPricesCommand, LoadInventoryCommand])
expect(intent.mode).toBe('allSettled')
})
it('plusClicked runs a single command', () => {
const intent = TestIntent(CounterIntents.plusClicked)
expect(intent.commands).toHaveLength(1)
expect(intent.commands).toEqual([IncrementCommand])
expect(intent.mode).toBe('sequential')
})
})

TestIntent는 가벼운 건전성 검사예요. 다음과 같은 경우에 사용해요:

  • Intent가 여러 Command를 연결할 때. Command가 올바르고 순서가 맞는지 확인해요.
  • Intent가 병렬 실행을 사용할 때. 모드가 실수로 sequential이 아닌 all 또는 allSettled인지 확인해요.
  • Command 구조를 리팩터링할 때. TestIntent 테스트는 Command가 추가, 제거, 또는 순서 변경되면 즉시 실패해요.

단일 Command에 sequential 모드인 Intent의 경우, 테스트는 간단하지만 Intent의 의도를 문서화하는 데 여전히 가치가 있어요:

expect(intent.commands).toEqual([IncrementCommand])
expect(intent.mode).toBe('sequential')