Async Tests Of Flow Methods With Mobx

Mark Stephenson
2 min readFeb 1, 2021

--

If you are using Mobx in a production application you will likely end up using ‘flows’ to help simplify working with actions.

In short this means replacing your async methods with a @flow wrapper around a generator function, and instead of awaiting your promises you yield them.

In our application architecture we use a presenters in a presentation layer, and it is through these that we test our system (shout out to Pete Heard at Logic Room).

In each of our tests we new up a presenter, make assertions, call methods then make further assertions that prove out our test cases. Nothing unusual here.

In our application we have made the decision, in some places, to not await some of the calls that our presenters make. We want the application to trigger a call that will result in an API call and a subsequent state change, but we don’t want the thread to be active while all that happens. We want to fire and forget. When the state eventually changes, this will be observed and the application UI updated eventually.

Now comes the issue.

How do you test, using mobx, an async method where the method under test is fire and forget?

What we didn’t want to do was await the calls in our presenter methods in order to satisfy the test. No tails wagging the dog here!

The answer is ‘when’.

when( predicate(), effect() )

In the longer form, when the predicate condition is met the effect is ran.

This didn’t solve our async issue as Jest tests would just run on past the effect, complete and exit the tests and then evaluate the effect when the predicate returned true.

In the SHORT form of when() a promise is returned. This means that you can use this as a smart waiting method within your tests and actually check the desired application behaviour.

// Usage Example 1
await when (() => presenter.foo === true)
OR// Usage Example 2
when (() => presenter.foo === true))
.then(() => {console.log('winning'})

We’re still experimenting and learning how best to use Mobx, so if you can see a better way of solving this issue feel free to let me know :)

--

--