3

I am trying to use Firebase as the backend for my app. If I use the following quickstart guide within my app everything works.

If I check on my firebase data page, data is successfully written.

However if I try to do the same thing inside of an androidTest (instrumentation test) nothing happens - no data is written to the firebase database. I have specified Internet permission in my androidTest manifest, so wondering if there is something else that I need to do to be able to write to firebase from within my tests?

On a related note, once I can do this within instrumentaiton tests, is there a way I can do the same in unit tests?

Many thanks,

Riz

Edit: here is the test I'm trying to run:

public class FirebaseTest extends InstrumentationTestCase{
    private static final String FIREBASE = "https://my-app-name.firebaseio.com/";

    @Override
    @Before
    public void setUp() {
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        Firebase.setAndroidContext(getInstrumentation().getTargetContext());
    }

   @Test
   public void testWrite(){
       Firebase cloud = new Firebase(FIREBASE);
       cloud.child("message").setValue("Do you have data? You'll love Firebase.");
   }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
chdryra
  • 523
  • 5
  • 17
  • I'm having the same issue, but for the sake of clarity can you edit your question to include an example of a test? – Travis Christian Mar 15 '16 at 15:51
  • I've edited the question to include the test I'm trying to run. – chdryra Mar 15 '16 at 19:09
  • Your class should extend Application or Activity for this to work or what you can do is create an application class and do the initial set up there as `Firebase.setAndroidContext(this);`on the oncreate and then further do your work – 1shubhamjoshi1 Mar 15 '16 at 19:12
  • @1shubhamjoshi1: I don't think extending an activity matters. In my app I put firebase in a helper class with no reference to an activity. I pass a context to the helper class and it works fine. In the instrumentation test above I pass the target context which should be the same thing, – chdryra Mar 16 '16 at 10:30

1 Answers1

1

In your main application you can define an androidApplication class to initialize your Firebase Context. Then create an ApplicationTest that extends the ApplicationTestCase :

In Main source :

public class MyApplication extends android.app.Application {

    @Override
    public void onCreate() {
       super.onCreate();
       Firebase.setAndroidContext(this); //initializeFireBase(context);
       isInitialized = true;
    }
}

In your Android Test :

public class ApplicationTest extends ApplicationTestCase<MyApplication> {

    private static MyApplication application;

    public ApplicationTest() {
        super(MyApplication.class);
    }

   @Override
   public void setUp() throws Exception {
      super.setUp();
      if (application == null) {
          application = getApplication();
      }
      if (application == null) {
         application = (MyApplication) getContext().getApplicationContext();
         assertNotNull(application);
         long start = System.currentTimeMillis();
         while (!application.isInitialized()){
             Thread.sleep(300);  //wait until FireBase is totally initialized
             if ( (System.currentTimeMillis() - start ) >= 1000 )
                 throw new TimeoutException(this.getClass().getName() +"Setup timeOut");
         }
      }
   }


   @Test
   public void testWrite(){
       Firebase cloud = new Firebase(FIREBASE);
       cloud.child("message").setValue("Do you have data? You'll love Firebase.");
   }

}
ThierryC
  • 1,794
  • 3
  • 19
  • 34
  • Thanks, I have tried this but doesn't work. The test fails to start as it cannot create the MyApplication via createApplication() (btw I think there should be a super.setup(); createApplication(); in a setUp method that runs before each test). It fails on Instrumentation.newApplication(mApplicationClass, getContext()); in ApplicationTestCase.java... – chdryra Mar 16 '16 at 15:30
  • to avoid to pass several times in the "onCreate()" method , I did an ugly setUp with store "MyApplication" in static mode. I will edit my answer to show you – ThierryC Mar 16 '16 at 15:37
  • Thanks for the reply. Unfortunately trying to run the above code I get an exception at the line: application = (MyApplication) getContext().getApplicationContext();. It's a NullPointerException somewhere in the JUnitRunner I think (in ReflectiveCallable.java). – chdryra Mar 16 '16 at 16:12
  • Are you sure your test Class extend android.test.ApplicationTestCase ? And if you use AndroidStudio don't forget in the Build Variant tab to select the Android Instrumentation Tests !! – ThierryC Mar 16 '16 at 17:01
  • What is InitializeFirebase? Is that where you would call Firebase.setAndroidContext? – Travis Christian Mar 16 '16 at 17:38
  • @toofoo: yes I just copied and pasted your code exactly. I changed InitializeFirebase to Firebase.setAndroidContext(this) otherwise the same. It seems to be the same problem as this http://stackoverflow.com/questions/14205451/android-applicationtestcase-using-a-mockcontext but can't use the solution as need a real context rather than mock one. – chdryra Mar 16 '16 at 19:17
  • "Firebase.setAndroidContext(this)" should work ; try to retrieve a data before trying to write something in the firebase database, and check the error message if there is one. – ThierryC Mar 17 '16 at 09:06
  • The error comes from trying to create the activity not from accessing Firebase. The test runner cannot instantiate MyApplication. I remove all references to Firebase, have a simple MyApplication that only has Super.onCreate() inside its own onCreate(), have an empty test with only createApplication() within the setup() and I get the same error. .. – chdryra Mar 21 '16 at 10:38
  • In Android Studio: In your module's build.graddle file you should have the line : testCompile 'junit:junit:4.12' Then on the "Build Variants" tab (of android Studio) in the "Test Artifacts" combo box select: "Android Instrumentation Tests" And for your module choose the Debug build variant – ThierryC Mar 22 '16 at 10:50
  • Thanks. Actually I have all that already. btw for instrumentation tests should be androidTestCompile 'junit:junit:4.12' I think. No problem with any of myother Junit 4 instrumentation tests just ones that are ApplicationTestCases... – chdryra Mar 22 '16 at 13:48
  • I don't know if it's the same for you but I'am using a real Device to run the Tests (it's too long and never succed with emulation). – ThierryC Mar 23 '16 at 10:38
  • Yeah I'm using a real device too. – chdryra Mar 24 '16 at 15:20