Currently, unit testing for integration with Firebase Messaging is very challenging. The encapsulation imposed by the final and visibility of the method makes it untestable. On top of this, there is no emulator for Firebase messaging which could help with testing integration with a more production-like environment.
1) I want to emulate exceptions on FCM Messaging like UNREGISTERED, INVALID_ARGUMENT when calling com.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message) to test my error handling implementation e.g deleting invalid token
com.google.firebase.messaging.FirebaseMessagingException is final thus mocking with popular libraries like Mockito is more difficult. We need to enable extra feature flags in Mockito to allow for mocking the class
It's impossible to create an instance of an exception with FCM Messaging exception as factory methods and constructors are package protected com.google.firebase.messaging.FirebaseMessagingException#withMessagingErrorCode
2) I want to unit test if a message with a given payalod was sent to FCM
Currently FCM payload represented with com.google.firebase.messaging.Message is not accessible to third parties via getters.
Assuming I want to test if a proper payload was sent via com.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message) to FCM I would like to mock com.google.firebase.messaging.FirebaseMessaging and validate that com.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message) method was invoked with given data and token
In this case, developers used @VisibleForTesting for their purposes for testing while they totally forgot about developers who use their library and can not access the payload of the message. On top of this, there is no provided reasonable toString to make any assertions based on this.
Describe the solution you'd likeExceptions testing
Option 1
Relax encapsulation for com.google.firebase.messaging.FirebaseMessagingException by deleting "final" on class and make errorCode protected
Option 2
Make factory method public com.google.firebase.messaging.FirebaseMessagingException#withMessagingErrorCode
Messages testing
Option 1
Make getter public for com.google.firebase.messaging.Message#Message to allow accessing payload of FCM message
Option 2
Provide reasonable toString to allow asserting on the toString method
Describe alternatives you've considered
Provide emulator for FCM which allows emulating different scenarios including errors
Provide dedicated implementations for testing purposes, open for all users
Additional context
Too aggressive encapsulation in my opinion is harmful. Developers should balance encapsulation and testability, taking into account the users of their libraries not only their own goals to protect their code with all means available in Java which are not perfect
Currently, unit testing for integration with Firebase Messaging is very challenging. The encapsulation imposed by the final and visibility of the method makes it untestable. On top of this, there is no emulator for Firebase messaging which could help with testing integration with a more production-like environment.
1) I want to emulate exceptions on FCM Messaging like UNREGISTERED, INVALID_ARGUMENT when calling
com.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message)
to test my error handling implementation e.g deleting invalid tokencom.google.firebase.messaging.FirebaseMessagingException#withMessagingErrorCode
2) I want to unit test if a message with a given payalod was sent to FCM Currently FCM payload represented with
com.google.firebase.messaging.Message
is not accessible to third parties via getters.com.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message)
to FCM I would like to mock com.google.firebase.messaging.FirebaseMessaging and validate thatcom.google.firebase.messaging.FirebaseMessaging#send(com.google.firebase.messaging.Message)
method was invoked with givendata
andtoken
In this case, developers used
@VisibleForTesting
for their purposes for testing while they totally forgot about developers who use their library and can not access the payload of the message. On top of this, there is no provided reasonable toString to make any assertions based on this.Describe the solution you'd like Exceptions testing
errorCode
protectedcom.google.firebase.messaging.FirebaseMessagingException#withMessagingErrorCode
Messages testing
com.google.firebase.messaging.Message#Message
to allow accessing payload of FCM messageDescribe alternatives you've considered
Additional context Too aggressive encapsulation in my opinion is harmful. Developers should balance encapsulation and testability, taking into account the users of their libraries not only their own goals to protect their code with all means available in Java which are not perfect