KStateMachine / kstatemachine

KStateMachine is a Kotlin DSL library for creating state machines and statecharts.
https://kstatemachine.github.io/kstatemachine/
Boost Software License 1.0
339 stars 19 forks source link

How to test transition arguments in onEntry? #105

Closed phfeustel closed 1 day ago

phfeustel commented 2 days ago

In my current implementation, I'm using a transition argument to pass some data to the second state.

In the second state, I'm accessing the data via:

onEntry {
                val myData = it.transition.argument as MyData
}

In my test, I'm using

machine.startFromBlocking(state = second, argument = myData)

Debugging the test, it shows that myData does not end up in it.transition.argument but in it.argument, which leads to a failing test.

I tracked it down to makeStartTranisitionParams is not setting the argument in the Transition but just in the TransitionParams.

Do you have any advise on a proper test setup to test onEntry with a transition argument?

nsk90 commented 2 days ago

Hello, looks that due to using using of startFrom transition argument is never set by your production code. Yes as you correctly mentioned Event argument and Transition argument, are different types of arguments and they are not related to each other.

In a test you can get your transition reference by findTransition/requireTransition APIs https://github.com/KStateMachine/kstatemachine/blob/master/kstatemachine/src/commonMain/kotlin/ru/nsk/kstatemachine/state/TransitionStateApi.kt#L38

And set it's argument explicitly in test code.

Alternatively you can run the StateMachine from some earlier State, to process necessary Event in the test, to trigger your production code that sets the transition argument.

I cannot suggest something better than that.

phfeustel commented 1 day ago

Thank you very much for the hint!

In my test, I'm using now

machine.findTransition<StartEvent>()?.argument = myData

which works out fine!

nsk90 commented 19 hours ago

For test code I recommend using "require" version, to end up with an exception if the transition will not be found. Using "find" + "?" which is effectively "if" may make the test false positive. 🤓