Unit Testing with Mockito & Firebase












1















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 ... //
}









share|improve this question




















  • 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















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 ... //
}









share|improve this question




















  • 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








1








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 ... //
}









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer


























  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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.






share|improve this answer


























  • 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
















1














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.






share|improve this answer


























  • 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














1












1








1







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)