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?
$5 per hour for each physical device. $1 per hour for each virtual device.
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.
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.
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With