Friday, 20 November 2020

"Check that you have added the HiltAndroidRule" for ContentProvider in a test

I have an instrumented test that starts an application with a content provider.

The test is straightforward:

@HiltAndroidTest
@UninstallModules({...})
public class MyTest {
  @Rule
  public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

  @Test
  ...
}

However, the application under test includes a ContentProvider, and this provider is using Hilt to inject data:

public class MyProvider extends ContentProvider {

  @EntryPoint
  @InstallIn(ApplicationComponent.class)
  interface MyProviderEntryPoint {
    @SqliteDatabaseName String databaseName();
  }

  @Override
  synchronized public boolean onCreate() {
    Context appContext = getContext().getApplicationContext();
    MyProviderEntryPoint entryPoint =
        EntryPointAccessors.fromApplication(appContext, MyProviderEntryPoint.class);
    mOpenHelper = new SqliteStoreOpener(getContext(), entryPoint.databaseName());

    return true;
  }

This causes the test to crash on startup:

java.lang.RuntimeException: Unable to get provider com.test.MyProvider: java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule.
    at android.app.ActivityThread.installProvider(ActivityThread.java:6242)
    at android.app.ActivityThread.installContentProviders(ActivityThread.java:5805)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5722)
    at android.app.ActivityThread.-wrap1(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule.
    at dagger.hilt.internal.Preconditions.checkState(Preconditions.java:83)
    at dagger.hilt.android.internal.testing.TestApplicationComponentManager.generatedComponent(TestApplicationComponentManager.java:79)
    at dagger.hilt.android.testing.HiltTestApplication.generatedComponent(HiltTestApplication.java:49)
    at dagger.hilt.EntryPoints.get(EntryPoints.java:46)
    at dagger.hilt.android.EntryPointAccessors.fromApplication(EntryPointAccessors.java:36)
    at com.test.MyProvider.onCreate(EboBirthdayProvider.java:114)
    at android.content.ContentProvider.attachInfo(ContentProvider.java:1917)
    at android.content.ContentProvider.attachInfo(ContentProvider.java:1892)
    at android.app.ActivityThread.installProvider(ActivityThread.java:6239)
    at android.app.ActivityThread.installContentProviders(ActivityThread.java:5805) 
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5722) 
    at android.app.ActivityThread.-wrap1(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

I suppose the problem is that the framework is trying to install the provider before Hilt even had a chance to start up and create the components. What's the proper setup to allow Hilt to run first and then construct the providers? For reference, I have a simple test runner:

public class MyRunner extends AndroidJUnitRunner {

  @Override
  public Application newApplication(ClassLoader cl, String className, Context context)
      throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return super.newApplication(cl, HiltTestApplication.class.getName(), context);
  }


from "Check that you have added the HiltAndroidRule" for ContentProvider in a test

No comments:

Post a Comment