Unit Testing with Mockito & Firebase
I am attempting to implement testing for an android app that I'm building. One of the tests involves an interactor file I wrote (DatabaseInteractor.java
) that connects to Google Firestore. The default constructor sets the FirestoreFirebase
object to FirebaseFirestore.getInstance();
.
I am using Mockito & JUnit for my unit tests. When I attempt to create a DataBaseInteractor object in my Unit Test, I get the following error:
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process null. Make sure to call FirebaseApp.initializeApp(Context) first.
Apparently this error occurs when the default constructor is called in my Unit Test. I'm not sure why this is happening. I am able to create a DataBaseInteractor object in other parts of my android app without issue. Are there perhaps limitations to when and where I can initialize a class that utilizes FireBaseFireStore
objects? If I want to mock the behavior of FireBase for unit testing, how do I get around these restrictions?
EDIT: A truncated version of my DataBaseInteractor.java
file:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor() {
db = FirebaseFirestore.getInstance();
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
android firebase unit-testing mockito google-cloud-firestore
add a comment |
I am attempting to implement testing for an android app that I'm building. One of the tests involves an interactor file I wrote (DatabaseInteractor.java
) that connects to Google Firestore. The default constructor sets the FirestoreFirebase
object to FirebaseFirestore.getInstance();
.
I am using Mockito & JUnit for my unit tests. When I attempt to create a DataBaseInteractor object in my Unit Test, I get the following error:
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process null. Make sure to call FirebaseApp.initializeApp(Context) first.
Apparently this error occurs when the default constructor is called in my Unit Test. I'm not sure why this is happening. I am able to create a DataBaseInteractor object in other parts of my android app without issue. Are there perhaps limitations to when and where I can initialize a class that utilizes FireBaseFireStore
objects? If I want to mock the behavior of FireBase for unit testing, how do I get around these restrictions?
EDIT: A truncated version of my DataBaseInteractor.java
file:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor() {
db = FirebaseFirestore.getInstance();
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
android firebase unit-testing mockito google-cloud-firestore
1
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42
add a comment |
I am attempting to implement testing for an android app that I'm building. One of the tests involves an interactor file I wrote (DatabaseInteractor.java
) that connects to Google Firestore. The default constructor sets the FirestoreFirebase
object to FirebaseFirestore.getInstance();
.
I am using Mockito & JUnit for my unit tests. When I attempt to create a DataBaseInteractor object in my Unit Test, I get the following error:
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process null. Make sure to call FirebaseApp.initializeApp(Context) first.
Apparently this error occurs when the default constructor is called in my Unit Test. I'm not sure why this is happening. I am able to create a DataBaseInteractor object in other parts of my android app without issue. Are there perhaps limitations to when and where I can initialize a class that utilizes FireBaseFireStore
objects? If I want to mock the behavior of FireBase for unit testing, how do I get around these restrictions?
EDIT: A truncated version of my DataBaseInteractor.java
file:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor() {
db = FirebaseFirestore.getInstance();
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
android firebase unit-testing mockito google-cloud-firestore
I am attempting to implement testing for an android app that I'm building. One of the tests involves an interactor file I wrote (DatabaseInteractor.java
) that connects to Google Firestore. The default constructor sets the FirestoreFirebase
object to FirebaseFirestore.getInstance();
.
I am using Mockito & JUnit for my unit tests. When I attempt to create a DataBaseInteractor object in my Unit Test, I get the following error:
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process null. Make sure to call FirebaseApp.initializeApp(Context) first.
Apparently this error occurs when the default constructor is called in my Unit Test. I'm not sure why this is happening. I am able to create a DataBaseInteractor object in other parts of my android app without issue. Are there perhaps limitations to when and where I can initialize a class that utilizes FireBaseFireStore
objects? If I want to mock the behavior of FireBase for unit testing, how do I get around these restrictions?
EDIT: A truncated version of my DataBaseInteractor.java
file:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor() {
db = FirebaseFirestore.getInstance();
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
android firebase unit-testing mockito google-cloud-firestore
android firebase unit-testing mockito google-cloud-firestore
edited Nov 25 '18 at 23:41
Chris T
asked Nov 25 '18 at 23:21
Chris TChris T
1868
1868
1
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42
add a comment |
1
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42
1
1
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42
add a comment |
1 Answer
1
active
oldest
votes
You need to inject the FirebaseFirestore instance in your constructor so that it can be mocked, something like:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor(FirebaseFirestore firestore) {
db = firestore
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
The in your test you can mock FirebaseFirestore
with Mockito:
@Test
public void someTest() {
FirebaseFirestore mockFirestore = Mockito.mock(FirebaseFirestore.class)
Mockito.when(mockFirestore.someMethodCallYouWantToMock()).thenReturn(something)
DatabaseInteractor interactor = new DatabaseInteractor(mockFirestore)
// some assertion or verification
}
I'd suggest you read about dependency injection, it will make unit testing a lot easier if you can pass in mocks of your dependencies in the constructor instead of instantiating them inside it.
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473006%2funit-testing-with-mockito-firebase%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need to inject the FirebaseFirestore instance in your constructor so that it can be mocked, something like:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor(FirebaseFirestore firestore) {
db = firestore
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
The in your test you can mock FirebaseFirestore
with Mockito:
@Test
public void someTest() {
FirebaseFirestore mockFirestore = Mockito.mock(FirebaseFirestore.class)
Mockito.when(mockFirestore.someMethodCallYouWantToMock()).thenReturn(something)
DatabaseInteractor interactor = new DatabaseInteractor(mockFirestore)
// some assertion or verification
}
I'd suggest you read about dependency injection, it will make unit testing a lot easier if you can pass in mocks of your dependencies in the constructor instead of instantiating them inside it.
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
add a comment |
You need to inject the FirebaseFirestore instance in your constructor so that it can be mocked, something like:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor(FirebaseFirestore firestore) {
db = firestore
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
The in your test you can mock FirebaseFirestore
with Mockito:
@Test
public void someTest() {
FirebaseFirestore mockFirestore = Mockito.mock(FirebaseFirestore.class)
Mockito.when(mockFirestore.someMethodCallYouWantToMock()).thenReturn(something)
DatabaseInteractor interactor = new DatabaseInteractor(mockFirestore)
// some assertion or verification
}
I'd suggest you read about dependency injection, it will make unit testing a lot easier if you can pass in mocks of your dependencies in the constructor instead of instantiating them inside it.
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
add a comment |
You need to inject the FirebaseFirestore instance in your constructor so that it can be mocked, something like:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor(FirebaseFirestore firestore) {
db = firestore
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
The in your test you can mock FirebaseFirestore
with Mockito:
@Test
public void someTest() {
FirebaseFirestore mockFirestore = Mockito.mock(FirebaseFirestore.class)
Mockito.when(mockFirestore.someMethodCallYouWantToMock()).thenReturn(something)
DatabaseInteractor interactor = new DatabaseInteractor(mockFirestore)
// some assertion or verification
}
I'd suggest you read about dependency injection, it will make unit testing a lot easier if you can pass in mocks of your dependencies in the constructor instead of instantiating them inside it.
You need to inject the FirebaseFirestore instance in your constructor so that it can be mocked, something like:
public class DatabaseInteractor {
private static User theUser;
private FirebaseFirestore db;
private DocumentReference userData;
public DatabaseInteractor(FirebaseFirestore firestore) {
db = firestore
theUser = new User();
}
// ... various methods that add/retrieve Users from FireStore ... //
}
The in your test you can mock FirebaseFirestore
with Mockito:
@Test
public void someTest() {
FirebaseFirestore mockFirestore = Mockito.mock(FirebaseFirestore.class)
Mockito.when(mockFirestore.someMethodCallYouWantToMock()).thenReturn(something)
DatabaseInteractor interactor = new DatabaseInteractor(mockFirestore)
// some assertion or verification
}
I'd suggest you read about dependency injection, it will make unit testing a lot easier if you can pass in mocks of your dependencies in the constructor instead of instantiating them inside it.
edited Nov 26 '18 at 0:06
answered Nov 26 '18 at 0:01
Jorge GilJorge Gil
449315
449315
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
add a comment |
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
Jorge, thank you for this. Do you happen to know if you have to pass any dependency you are mocking in a class via the constructor, or this just a quirk of mocking Firebase objects?
– Chris T
Nov 26 '18 at 0:07
1
1
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
You don't have to, you could pass a mock via a method for example. But you probably should. Generally speaking, unit tests are meant to test a piece of code by itself without external dependencies. In your case, you want to test that the functionality of your interactor works, regardless of how the firestore, or any other dependency behaves. You can accomplish this by mocking all of the dependencies and the easy (and clean) way to do that is with constructor injection.
– Jorge Gil
Nov 26 '18 at 0:13
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473006%2funit-testing-with-mockito-firebase%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
post your DatabaseInteractor.java file, you probably need to mock the Firestore instance
– Jorge Gil
Nov 25 '18 at 23:36
Posted my DataBaseInteractor file!
– Chris T
Nov 25 '18 at 23:42