Тестирование логики акторов важно для обеспечения того, чтобы логика была корректной и вела себя ожидаемо. Вы можете тестировать свои машины состояний и акторы, используя различные библиотеки и инструменты тестирования. При написании тестов для машин состояний и акторов следует следовать паттерну Arrange, Act, Assert (Подготовка, Действие, Проверка):
Arrange (Подготовка) — настройте тест, создав логику акторов (например, машину состояний) и акторы из логики акторов.
import{setup,createActor}from'xstate';import{test,expect}from'vitest';test('some actor',async()=>{constnotifiedMessages:string[]=[];// 1. Подготовкаconstmachine=setup({actions:{notify:(_,params)=>{notifiedMessages.push(params.message);},},}).createMachine({initial:'inactive',states:{inactive:{on:{toggle:{target:'active'}},},active:{entry:{type:'notify',params:{message:'Active!'},},on:{toggle:{target:'inactive'}},},},});constactor=createActor(machine);// 2. Действиеactor.start();actor.send({type:'toggle'});// => должен быть в состоянии 'active'actor.send({type:'toggle'});// => должен быть в состоянии 'inactive'actor.send({type:'toggle'});// => должен быть в состоянии 'active'// 3. Проверкаexpect(actor.getSnapshot().value).toBe('active');expect(notifiedMessages).toEqual(['Active!','Active!',]);});
При тестировании акторов вы обычно хотите убедиться, что они переходят в правильное состояние и соответствующим образом обновляют свой контекст при получении событий.
import{setup,createActor}from'xstate';import{test,expect}from'vitest';test('actor transitions correctly',()=>{consttoggleMachine=setup({}).createMachine({initial:'inactive',context:{count:0},states:{inactive:{on:{activate:{target:'active',actions:assign({count:({context})=>context.count+1,}),},},},active:{on:{deactivate:'inactive',},},},});constactor=createActor(toggleMachine);actor.start();// Тест начального состоянияexpect(actor.getSnapshot().value).toBe('inactive');expect(actor.getSnapshot().context.count).toBe(0);// Отправка события и тест переходаactor.send({type:'activate'});expect(actor.getSnapshot().value).toBe('active');expect(actor.getSnapshot().context.count).toBe(1);// Отправка другого событияactor.send({type:'deactivate'});expect(actor.getSnapshot().value).toBe('inactive');expect(actor.getSnapshot().context.count).toBe(1);});
При тестировании машин состояний с побочными эффектами (такими как API-вызовы, логирование или другие внешние взаимодействия) следует мокировать эти эффекты, чтобы сделать тесты детерминированными и изолированными.
Утилиты модельного тестирования XState Test были перемещены в сам xstate и теперь доступны в xstate/graph. Отдельный пакет @xstate/test устарел в пользу интегрированных утилит тестирования.
Утилиты модельного тестирования позволяют автоматически генерировать тестовые случаи из ваших машин состояний, обеспечивая полное покрытие всех возможных путей и граничных случаев.