Testing state

Introduction

ConanJs makes testing end to end state simple.

This is because of some principles.

  • We use internally ASAPs, which work like a promises except that, if possible, they will run the promised code sequentially (only code that needs to be deferred will be deferred, like fetching data).

  • We provide with mechanisms to handle async actions out of the box

  • We provide with introspection so you can check if there is any operation running at the moment (even asynchronous ones)

That all together makes it so that you can have two main guarantees:

  • You will always be able to read the latest state from ConanState

  • You can easily execute actions and predict and react when they are settled so you can write your expectations

To showcase the features available for testing and to stay aways from picking a testing framework, we have put together an example that we will breakdown below

Testing simple actions

Sync Actions

To test for synchronous values there isn't anything special to do, as soon as the execution of the action is completed, the new state can be already be checked.

numberValue$.do.update(3);
//at this point the value of the state is 3
console.log(numberValue$.getData())
//this will print 3

Async Actions

To test for a single asynchronous action, the best approach is to chain the action with the actual test:

numberValue$.do.updateAsap(Asaps.delayed(3, 1000)).then ( ()=>{
//at this point the value of the state is 3
console.log(numberValue$.getData())
//this will print 3
})

Testing event list

We can query all the values that the ConanState has been updated to

No matter how many operations you perform in your Conan State, all the state changes are stored for you to query,

This is handy if you are not so interested in the last state, but in the sequence of states. You can see the details for getEvents() on the ConanState API page

For instance to get all the states as an array in the example in this page we use:

numberValue$.getEvents().serialize({
eventTypes: [StatusEventType.STATE],
excludeInit: true,
})
.map((it: StateEvent, i) => it.data != null ? it.data : '[undefined]')
.join(', ')

Testing using introspection

The ability to introspect the actual status of the Conan State can prove very helpful when testing complex actions.

Async actions without transactions

The first use case where this can be very handy is when it comes to waiting for a few async actions to complete.

As you can see, if you have overlapping async actions, you can just run them all together, and wait for the idle status which will be triggered as soon all of them all resolved.

Any action with transactions

For more complex cases, or when you want to bundle synchronous actions, you can leverage transactions.

If you open a transaction, the Conan State machine would not reach IDLE until the transaction should be IDLE AND the transaction is closed.

This could be useful if you are not sure of the nature of the timing of the actions that you are testing. In these cases, you could open a transaction, launch all of your actions, and then, close the transaction and listen for the next IDLE.

The feeling when you can easily test E2E your state

Demo