5

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?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Prokky
  • 815
  • 7
  • 19
  • Is it not possible to mock the firebase components? do you want them in your test? – wake-0 Jul 12 '16 at 13:10
  • No, I dont need them yet. Could you please provide more info about how to mock them? I'm new to testing. – Prokky Jul 12 '16 at 13:12

1 Answers1

4

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());
wake-0
  • 3,918
  • 5
  • 28
  • 45