Henrick Kakutalua
Henrick Kakutalua

Reputation: 107

Unit test a class that uses Firebase Auth

I'm unit testing a class - AuthenticationService - responsible for authenticating the user with Firebase Auth. I'm using JUnit, Mockito and PowerMock for this purpose.

I'm mocking completely Firebase Auth, as my main target is the logic contained within the class. My problem resides in this method:

public void loginWithEmailAndPassword(String email, String password, OnCompletedListener listener) {
    if (Strings.isNullOrEmpty(email) || !Pattern.compile(EMAIL_PATTERN).matcher(email).matches()) {
        throw new IllegalArgumentException("email field is empty or bad formatted");
    }
    if (Strings.isNullOrEmpty(password)) {
        throw new IllegalArgumentException("password field must be not empty");
    }

    mFirebaseAuth.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener(task -> {
                if (task.isSuccessful()) {
                    if (listener != null)
                        listener.onComplete(new AuthResult(true, null));
                } else {
                    Exception exception = (FirebaseAuthException)task.getException();
                    Log.e(TAG, exception.getMessage());
                    if (listener != null) {
                        AuthResult result = new AuthResult(false, createStatusFromFirebaseException(exception));
                        listener.onComplete(result);
                    }
                }
            });
}

I want to test the lambda method passed in addOnCompleteListener. I know i need to somehow call this lambda method, because Firebase itself will never call it, i'm mocking Firebase after all.

The problem is: i don't have any idea of how to call this lambda method in my unit test code. I need to test if the onComplete method is being called in the listener, and it's arguments.

Thanks in advance.

Upvotes: 0

Views: 5326

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317322

You've having difficulty doing true unit testing here because you're actually trying to test two classes, not just one. Pure unit tests only work with a single class under test - everything else is mocked or stubbed.

The second class here that's not immediately obvious is the OnCompleteListener that you're passing to mFirebaseAuth.signInWithEmailAndPassword().addOnCompleteListener(). If you factor that out and test it separately, your outer class will become possible to properly unit test.

If you do this, now you have an opportunity to also unit test the OnCompleteListener on its own by passing it a mocked Task and checking if it does the right thing with it and the mock OnCompletedListener that you're passing to loginWithEmailAndPassword.

To summarize: you have a fair amount of refactoring to do here to make this class able to be properly unit tested.

Upvotes: 3

Related Questions