#are .on callbacks deferred?

1 messages · Page 1 of 1 (latest)

swift light
#

I'm trying to test a state machine, specifically that an emit is run. In my test, I'm starting the actor with createActor, subscribing with .on, then sending the machine an event that should result in the callback being called. Problem is, it looks like the callback is never called for some reason.

This is strange, because I can get the response messages in my actual app, just not the tests. I wonder if it's something to do with using @xstate/vue vs createActor directly?

Here's the test that fails:

  it("should emit a message to add to the stack if we accept a todo", () => {
    const doc = init()
    const id = addTodo(doc, "A")

    const machine = createActor(stackBuilderMachine, { input: doc })

    const spy = vi.fn()
    machine.on("addToStack", (ev) => spy(ev))

    machine.send({ type: "review", result: "yes" })

    expect(spy).toHaveBeenCalledWith({ type: "addToStack", id })
  })

(I thought at first this was me not understanding how spies work, but adding a throw in the on callback does not work either!)

Here's the machine, in case it's helpful: https://gist.github.com/BrianHicks/c74b318e9e0273ed504cb2e5b46b5f9b

Any ideas what could be going on here?

Gist

GitHub Gist: instantly share code, notes, and snippets.

civic gate
#

You should treat them as deferred, even if they're not, in tests

#

Try adding a timeout, or expect.assertions(1) and asserting directly in the emit handler callback

#

Or do an async test:

machine.on('addToStack', ev => {
  expect(ev)...
  resolve();
})
swift light
#

mm, ok. I'll give that a shot. Thanks

swift light
#

BTW it looks like the problem was that I had never called machine.start()

civic gate
#

Ahh okay