Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robolectric app testing with Firebase

Tags:

I'm trying to write a simple Robolectric test for my presenter, which uses the Firebase Database and Firebase Auth. But every time I'm trying to start the test, it throwes an IllegalStateException.

java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist. 
    at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
    at com.google.firebase.FirebaseApp.getInstance(Unknown Source)
    at com.google.firebase.auth.FirebaseAuth.getInstance(Unknown Source)

My test is quite simple

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class LoginPresenterTest {
    private LoginPresenter presenter;
    private LoginMvpView view;

    @Before
    public void beforeEachTest() {
        presenter = new LoginPresenter();
        view = new LoginFragment();
    }

    @Test
    public void attachView_shouldAttachViewToThePresenter() {
        presenter.attachView(view);
        assertSame(presenter.getMvpView(), view);
    }
}

While in my presenter constructor I just get the Firebase instances.

public LoginPresenter() {
        this.firebaseAuth = FirebaseAuth.getInstance();
        this.database = FirebaseDatabase.getInstance().getReference();
    }

Is there any way to use the Robolectric with Firebase?

like image 201
Prokky Avatar asked Jul 12 '16 13:07

Prokky


People also ask

Is firebase test lab free?

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

Can I use Firebase for my app?

Firebase Authentication works across Android, iOS and the web making it a great choice when you think your user is likely to be accessing your app across different devices. Other capabilities offered by Firebase Authentication not mentioned above include.

What is a robo test?

Note: Robo test is not the same as (or based on) the Robotium or Robolectric test frameworks. Robo test is a testing tool that is integrated with Firebase Test Lab. Robo test analyzes the structure of your app's user interface (UI) and then explores it methodically, automatically simulating user activities.


1 Answers

If you don't use them in your code to test it is possible to inject them by constructor:

public LoginPresenter(FireBaseAuth firebaseAuth, FirebaseDatabase database){
    this.firebaseAuth = firebaseAuth;
    this.database = database;
}

and you inject null for them, remember this is a very poor way by using null. The much better way is to use a library like Mockito or use interfaces/wrapper etc.

E.g. use an interface

public interface IDatabase {
    public List<String> getData();
}

The LoginPresenter:

public LoginPresenter(FireBaseAuth firebaseAuth, IDatabase database){
    this.firebaseAuth = firebaseAuth;
    this.database = database;
}

The normal implementation of the IDatabase:

public class MyDatabase implements IDatabase {

    private FirebaseDatabase database;

    public MyDatabase(FirebaseDatabase database) {
        this.database = database;
    }

    public List<String> getDate() {
        // Use the FirebaseDatabase for returning the getData
        return ...;
    }
}

And now it is very easy to mock the database by using the IDatabase:

public class DatabaseMock implements IDatabase {
    public List<String> getData() {
        // Return the expected data from the mock
        return ...;
    }
}

Call it from the test like:

 presenter = new LoginPresenter(FirebaseAuth.getInstance(), new DatabaseMock());
like image 70
Kevin Wallis Avatar answered Oct 11 '22 18:10

Kevin Wallis