1

我已经实现了一个 ContentProvider,它使用 Room 数据库来存储数据。该实现是在 kotlin 中完成的,它遵循这个Google 示例中显示的相同模式。ContentProvider 在应用程序中使用时可以正常工作。现在我想写一些测试,我依靠 ProviderTestRule 来做这件事。我的配置看起来不错,但不幸的是我得到了以下异常,看起来缺少一些初始化,然后上下文不可用。

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)

我找不到任何关于如何测试这种情况的示例。任何提示都会非常有帮助!

4

1 回答 1

0

ProviderTestRule内部使用DelegatingContext,它是围绕应用程序上下文的包装器,故意限制其功能。

从源代码中你可以看到它被存根,大部分时间都在context.getSystemService抛出:UnsupportedOperationException

  /**
   * 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();
  }

我没有明确解释为什么他们ProviderTestRule首先禁止访问系统服务。不幸的是,似乎 Room 需要访问ActivityManager才能找到最合适的JournalMode.

您可以尝试解决这种情况的方法:

  1. 强制JournalMode您的 Room 数据库为JournalMode.WRITE_AHEAD_LOGGING(或JournalMode.TRUNCATE),或
  2. 如果它不能解决这种情况,您必须编写自己的ProviderTestRule,使用真实的应用程序上下文并允许访问所需的系统服务。
于 2021-08-07T08:19:20.730 回答