[XState] Using global actions prop for testing

Let's say we have a State Machine Model:

import { createMachine, interpret } from "xstate";

const elBox = document.querySelector("#box");

const setPoint = (context, event) => {
  // Set the data-point attribute of `elBox`
  // ...
  elBox.dataset.point = `${event.clientX} - ${event.clientY}`;
};

const machine = createMachine(
  {
    initial: "idle",
    states: {
      idle: {
        on: {
          mousedown: {
            // Add your action here
            // ...
            target: "dragging",
            actions: [setPoint],
          },
        },
      },
      dragging: {
        on: {
          mouseup: {
            target: "idle",
          },
        },
      },
    },
  }
);

const service = interpret(machine);

service.onTransition((state) => {
  elBox.dataset.state = state.value;
});

service.start();

elBox.addEventListener("mousedown", (event) => {
  service.send(event);
});

elBox.addEventListener("mouseup", (event) => {
  service.send(event);
});

 

We have inline action for 'idle' state when mousedown event happen, it call 'setPoint' function.

 

Question is how to test those actions get triggered in Unit testing?

We can use global 'actions' prop to override existing inline function:

const machine = createMachine(
  {
    initial: "idle",
    states: {
      idle: {
        on: {
          mousedown: {
            // Add your action here
            // ...
            target: "dragging",
            actions: [setPoint],
          },
        },
      },
      dragging: {
        on: {
          mouseup: {
            target: "idle",
          },
        },
      },
    },
  },
  {
    actions: {
      setPoint: () => {
        console.log("set point");
      },
    },
  }
);

Now it will only response with console log. That can be used in Unit testing with some ENV case switcher.

 

posted @ 2020-07-20 22:25  Zhentiw  阅读(165)  评论(0编辑  收藏  举报