Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit Testing in Android Studio with Firebase

I want to write a Unit test for this class in Android Studio, but I am having problem creating test to cover usersignin() and getSignedinUserprofile() because of the use of Firebase. Does anyone have any experience with this?

public class LoginActivity extends AppCompatActivity implements View.OnClickListener{


private Button buttonSignIn;
private EditText editTextEmail;
private EditText editTextPassword;
private TextView textViewSignUp;

private ProgressDialog mProgressDialog;
private FirebaseAuth mfireBaseAuth;
private DatabaseReference mDatabase;
private String userID;
private FirebaseUser firebaseUser;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    FirebaseApp.initializeApp(this);

    mfireBaseAuth = FirebaseAuth.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference();
    mProgressDialog = new ProgressDialog(this);
    editTextEmail = (EditText) findViewById(R.id.editTextEmail);
    editTextPassword = (EditText) findViewById(R.id.editTextPassword);
    buttonSignIn = (Button) findViewById(R.id.buttonSignIn);
    textViewSignUp = (TextView) findViewById(R.id.textViewSignUp);

    buttonSignIn.setOnClickListener(this);
    textViewSignUp.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    if(v == buttonSignIn){
        usersignin();}
    if(v==textViewSignUp){
        startActivity(new Intent(this, RegisterActivity.class));}


}

public void usersignin() {

    String email = editTextEmail.getText().toString().trim();
    String password = editTextPassword.getText().toString().trim();

    if(TextUtils.isEmpty(email)){
        Toast.makeText(this, "Please enter Email", Toast.LENGTH_SHORT).show();
        return;
    }

    if(TextUtils.isEmpty(password)){
        Toast.makeText(this, "Please enter password", Toast.LENGTH_SHORT).show();
        return;
    }

    mProgressDialog.setMessage("Logging in. Please wait...");
    mProgressDialog.show();
    mfireBaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            mProgressDialog.dismiss();
            if(task.isSuccessful()){
                getSignedInUserProfile();
            }
        }
    });
}

public void getSignedInUserProfile() {

    DatabaseReference reference = mDatabase;//.child("eduback-2feef");
    firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    userID = firebaseUser.getUid();
    reference.child("Users").child(userID).child("User info").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            User user = dataSnapshot.getValue(User.class);
            if(user != null) {
                // Save if the user is student or prof in shared prefs.
                PreferenceHelper helper = new PreferenceHelper(getBaseContext());
                helper.setIsStudent(user.isStudent);
                checkStudentOrProfessor(user);
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Ups vis error
        }
    });
}

public void checkStudentOrProfessor(User user) {

    Intent i;
    if (user.isStudent ) {
        i = new Intent(this, MainActivityStudent.class);
    } else {
        i = new Intent(this, MainActivityProfessor.class);
    }
    startActivity(i);
}
like image 665
MeryT Avatar asked Apr 05 '17 08:04

MeryT


People also ask

Can you use Firebase with Android Studio?

Firebase is made up of complementary features that you can mix-and-match to fit your needs, with Google Analytics for Firebase at the core. You can explore and integrate Firebase services in your app directly from Android Studio using the Assistant window shown in figure 1.

How Android Junit framework performs testing of an Android app?

Unit testing is done to ensure that developers write high-quality and errorless code. It is advised to write Unit tests before writing the actual app, you will write tests beforehand and the actual code will have to adhere to the design guidelines laid out by the test.

Is firebase Testlab free?

$5 per hour for each physical device. $1 per hour for each virtual device.


1 Answers

You can use Mockito and PowerMockito to mock Firebase dependencies. For mocking static functions (like FirebaseDatabase.getInstance()) PowerMockRunner must be used to run the test but it can delegate to different runner later.

package com.test.firebasetest;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(JUnit4.class)
@PrepareForTest({ FirebaseDatabase.class})
public class LoginActivityTest {

  private DatabaseReference mockedDatabaseReference;

  @Before
  public void before() {
    mockedDatabaseReference = Mockito.mock(DatabaseReference.class);

    FirebaseDatabase mockedFirebaseDatabase = Mockito.mock(FirebaseDatabase.class);
    when(mockedFirebaseDatabase.getReference()).thenReturn(mockedDatabaseReference);

    PowerMockito.mockStatic(FirebaseDatabase.class);
    when(FirebaseDatabase.getInstance()).thenReturn(mockedFirebaseDatabase);
  }

  @Test
  public void getSignedInUserProfileTest() {
    when(mockedDatabaseReference.child(anyString())).thenReturn(mockedDatabaseReference);

    doAnswer(new Answer<Void>() {
      @Override
      public Void answer(InvocationOnMock invocation) throws Throwable {
        ValueEventListener valueEventListener = (ValueEventListener) invocation.getArguments()[0];

        DataSnapshot mockedDataSnapshot = Mockito.mock(DataSnapshot.class);
        //when(mockedDataSnapshot.getValue(User.class)).thenReturn(testOrMockedUser)

        valueEventListener.onDataChange(mockedDataSnapshot);
        //valueEventListener.onCancelled(...);

        return null;
      }
    }).when(mockedDatabaseReference).addListenerForSingleValueEvent(any(ValueEventListener.class));

    new LoginActivity().getSignedInUserProfile();

    // check preferences are updated
  }

}

You need to add appropriate dependencies to you module build.gradle:

testCompile 'junit:junit:4.12'
testCompile 'org.powermock:powermock:1.6.5'
testCompile 'org.powermock:powermock-module-junit4:1.6.5'
testCompile 'org.powermock:powermock-api-mockito:1.6.5'
like image 189
Petr Šabata Avatar answered Oct 01 '22 19:10

Petr Šabata