简体   繁体   中英

How to test ContentProvider with ProviderTestRule in kotlin

I have implemented a ContentProvider that uses a Room database to store the data. The implementation is done in kotlin and it follows the same pattern shown in this Google example . The ContentProvider works fine when used in an app. Now I want to write some tests and I am relying on ProviderTestRule for doing so. The configuration I have seems fine, but unfortunately I am getting the following exception, which looks like some initialisation is missing and then the context is not available.

java.lang.UnsupportedOperationException
at androidx.test.rule.provider.DelegatingContext.getSystemService(DelegatingContext.java:277)
at androidx.room.RoomDatabase$JournalMode.resolve(RoomDatabase.java:517)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:943)

I wasn't able to find any example of how to test this scenario. Any hint would be really helpful!

ProviderTestRule internally uses DelegatingContext , which is a wrapper around the application context that purposely limits its capabilities.

From the source code you can see that context.getSystemService is stubbed out, throwing UnsupportedOperationException most of the time:

  /**
   * This method only supports retrieving {@link android.app.AppOpsManager}, which is needed by
   * {@link android.content.ContentProvider#attachInfo}.
   */
  @Override
  public Object getSystemService(@NonNull String name) {
    checkArgument(!TextUtils.isEmpty(name), "name cannot be empty or null");
    // getSystemService(Context.APP_OPS_SERVICE) is only used in ContentProvider#attachInfo for
    // API level >= 19.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
        && Context.APP_OPS_SERVICE.equals(name)) {
      return context.getSystemService(Context.APP_OPS_SERVICE);
    }
    throw new UnsupportedOperationException();
  }

I have no clear explaination why they forbid access to system services for ProviderTestRule in the first place. Unfortunately, it seems that Room requires access to the ActivityManager in order to find the most appropriate JournalMode .

What you can try to workaround the situation:

  1. Force the JournalMode of you Room database to JournalMode.WRITE_AHEAD_LOGGING (or JournalMode.TRUNCATE ), or
  2. If it did not solve the situation, you'd have to write your own ProviderTestRule that uses the real application context to and allow access to the desired system service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM