Closed ibizaman closed 1 year ago
Hm, maybe this can be achieved by wrapping the "base" state machine type in several "derived" types which override the Init()
with the required initialization?
type stateMachine struct {
user userMethods
}
type dbStatMachine struct {
stateMachine
}
func (m *dbStateMachine) Init(t *rapid.T) {
sm.user, sm.close = setupUserDatabase(t)
}
// ...
Take this with a grain of salt because we didn't yet upgrade this package to use generics. But this works! The check
must be called like this:
rapid.Check(t, rapid.Run(& dbStateMachine{stateMachine{}}))
I'll report back when we upgraded to see if it still holds.
Allow to give a specializer when running the state machine
The use case is the following: we want to be able to test multiple implementations with the same state machine. Adding this
specialize
function allows to tweak the state machine after creation.A concrete example for us is testing database accessors. We have one struct with methods that accesses the real database and we're currently using
rapid
to test it with a state machine, and it's wonderful. But then, we want to create a stub that instead uses an in-memory data store and will be used in unit tests. Right now we're using mocks but would like to transition to stubs as maintaining the mocks gets hard now. But of course, we want to make sure the new stub matches the methods accessing the real database. This PR allows us to do the following:We can have multiple tests using the same state machine living at the same time:
And then have a common state machine for everything:
What do you think of this?