Unit Testing a Utility function that returns a Widget
Probably not too common a use case, but for me I have a utility function for handling in-app navigation from the in-app web view webview_flutter while it does have a generic error handler, I need to be handle errors differently based on what type of URL was selected as custom logic is required to be able to handle links that are not actually valid.
A snippet from the utility mentioned above:
In this case, groups is a URL path that we currently do not support within the flutter app, so there is other logic specifically for groups, but for brevitiy we will reference the generic _handleUnsupported function which returns a Snacbar with a localized error message.
Normally with a utility test, one would simply use expect, however in this case the functions result would be a visual element, so before we can expect anything, we need to setup a test to allow all the logic to run.
There are actually quite a few things happening here in this test, but the most important part is the setup on line 13. Here we are setting up a test implementation of the widget, the provideLocalizedWidgetForTesting is a test utility I setup, you can read about it HERE.
As the resulting Snackbar also makes use of context fot state access as well as localization I have included the LayoutBuilder to get hold of the context from the test utility.
The utility function itself is a Future and one of the easisest way to run those inside a widdget is with the FutureBuilder, which links back up to the future function on line 8. Here is simply included a short delay to help manage ui rendering within the test context, otherwise you end up with it failing as needsBuild get’s called.
So once we have settled and pumped that additional second, we are now able to expect the Widget that should be rendered on the screen.
As mentioned above, not a very common usecase, and when possible one should always keep UI and Utilities seperate, and after having written this I had found a better way to deal with it in my use case, a way that did not involve returning a widget from a utility.
I felt however the learning itself was still valuable, and the possibility does exist that this is an unavoidable scenario for someone, or even myself at a later stage. #SharingIsCaring
Hope you all enjoyed the read.