Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directly set the state for testing purposes #7

Open
bbil opened this issue Dec 11, 2018 · 3 comments
Open

Directly set the state for testing purposes #7

bbil opened this issue Dec 11, 2018 · 3 comments

Comments

@bbil
Copy link

bbil commented Dec 11, 2018

In my usage of this library, it is very inconvenient to set up unit tests where I want the state machine to be in a certain state. What I've been doing so far is creating utility functions that perform all the transitions necessary from the initial state to the desired state.

Is there a way to do what I am describing?

@zhxnlai
Copy link
Collaborator

zhxnlai commented Dec 11, 2018

Does this help? You can also modify transitions using with

@bbil
Copy link
Author

bbil commented Dec 11, 2018

Not quite, maybe I didn't explain everything completely.

In my use case, I have a wrapper class for state management, that internally uses this library to implement an FSM (a function of the wrapper class pushes events into the state machine). In order to set up my tests, I often want to get the state machine to be in a certain state. My solution thus far has been to just call a function on my wrapper class a bunch to cause state transitions. However, this is kinda clumsy and has the potential problem of breaking tests in an annoying way if the state graph is changed in an unexpected way.

What would be useful is a function like setState on the top-level StateMachine class that operates similarly to transition except without all the checks, and calling onExit and onEnter functions. This way, tests are easier to bootstrap.

Do you think you'd accept a PR that did something like this, or is there another creative solution out there?

edit: Due to f.lux being on, I didn't even realize you had a link in your post. Maybe I can use that... but it would basically involve me having to re-assign the state machine variable in my wrapper class. Which would mean I would need to change my val stateMachine = StateMachine.create { dsl code } into a var.

@ursusursus
Copy link

This is a big issue for me.

In general, the design seems to be that state machine should be a implementation detail of a given enclosing class. Sure you can proxy actions in, but then you need to assert on the state somehow, which might or might not be already exposed as a public api. If it is not, then you are having the lame @VisibleForTesting

What's worse is exactly jumpstarting the state machine into a state for a given test. This way you need to pass it in via ctor, which is leaking the implmentation detail to callsites. Maybe you can have a @VisibleForTesting setter for this, but you might run into trouble of stateMachine being initialized as a val already.

I don't think this is doable at all, unless state machine is passed in via ctor, which however means all the sideffecting code from within transition functions needs to be abstracted away, ughhh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants