I'm starting my journey with unit testing in Flutter. Early in the process, while I was writing tests for my Firebase sign in workflow, I faced a situation that I struggled to surpass and want to share. I needed it to test a static member call.
Concretely, I wanted to test a call to the GoogleAuthProvider.credential()
static method. I wanted to do this to get the OAuth credentials and pass them to FirebaseAuth.signInWithCredential()
. This way I could use Google Sign In through Firebase Authentication.
In my test, I couldn't mock this static method call. All my attempts failed. My only hope was to refactor my code to make it testable for this particular case.
After several failed attempts -such as creating a mock to override the static method, doing the same with Fake instead of Mock, etc-, I realized that the solution implies wrapping the call in a class, so I'll be able to test it indirectly. However, the test structure requires this new wrapper class to be passed as a dependency for the class where the relevant call takes place.
Well, the test will pass if I mock this new wrapper class and use it in when()
. But I didn't want to depend on this class and make my overall architecture ugly and ad-hoc.
Finally, I decided to make this little modification:
This way, making the dependency optional, I could mock my wrapper class, call it on when()
, and pass the test, without compromising my overall structure.
Also, this new wrapper eventually could serve as a place to implement additional forms of authentication, besides GoogleOAuthCredentials.
I'm learning a lot of unit testing with these kinds of situations and enjoying testing my apps. I hope eventually implement Widget and integration testing too for this same project.
Top comments (3)
I'm using this same pattern but I think this will break background messages for FirebaseMessaging. Static methods are available even after instances have been garbage collected & so I'm afraid this wrapper instance may not be available when the app is backgrounded ... any thoughts??
Hi if you don't mind how to take screenshots like that 😅.
haha I used carbon.now.sh