cobra
cobra copied to clipboard
No way to clear initializers for testing
If you use a function to create a new instance of a command to allow testing with different arg inputs without risk of state being preserved between tests, can run into an issue if also making use of cobra.OnInitialize()
.
Currently using cobra.OnInitialize()
to work around spf13/viper#397 as being able to mark some flags as required if a particular flag is not set before the preRun fires to check if all required flags are provided.
Similar in many ways to the code at https://github.com/spf13/viper/pull/852#issuecomment-592243347
However during testing I noticed that in order to be able to provide the cmd
instance for the function passed to cobra.OnInitialize()
it's necessary to have it part of the same function creating the command, which in turn means that each test that calls this is appending another function to the initializers at https://github.com/spf13/cobra/blob/master/cobra.go#L82-L84
This appears to cause a certain amount of interesting behaviour because each initializer will contain a reference to the command as created when that initializer was being appended, meaning the code will execute an initiailizer for however many instances of the command were created for testing.
When looking to trigger a panic by removing required flags in one of the tests via cmd.ResetFlags()
, this prevents any subsequent test from running because the initializers contain an instance of the code from https://github.com/spf13/viper/pull/852#issuecomment-592243347 that will attempt to always execute on an instance of the command missing flags.
To workaround, can move this test to be the last one, however it seems like it would be useful to have ResetInitializers()
function similar to the ResetFlags()
to facilitate testing of code that is making use of OnInitialize()
.
My current approach is flip flopping between
- move test to end
- restore removed flags to the command via a t.Cleanup and custom function to reattach all previously defined flags
- modify the function passed to
cobra.OnInitialize()
to limit it's execution to be once only and skipped subsequently allowing only the most recent addition to have an effect
This issue is being marked as stale due to a long period of inactivity
Unless I've missed an update this is still a problem
FWIW, I have the same problem - didn't find it when I tested here -https://github.com/spf13/cobra/issues/1367
My approach was always to separate out the logic from the CLI handling and to try and not avoid on the init type logic because of the issues you've described here.
When I couldn't get away from it, I moved whatever logic was in init
style methods and extract them so that my tests could call those manually. Then you end up without any repeated code except maybe an extra reference to this init logic.
The init logic can contain any generic logic though as opposed to resetting flags; its not always as trivial (or desirable) to re-run initializers and we'd be unable to 'undo' their effect in any general sense.
Could you clarify exactly what it is that you're hoping for as a result of this? In @aronchick 's issue they mention wanting to reset all the flags; is that it: to traverse the commands/parents/children and reset all the flags?
Same problem here. And it is sad to see unsolved issues being closed automatically by bots. 😞