如何使用Robolectric对PackageManager进行阴影处理

mja*_*ola 13 android shadow robolectric

我的Android应用程序有一个简单的方法来启动显示URL的意图.

protected void launchBrowser(int id)
{
    Uri uri = Uri.parse( getString( id ) );
    Intent intent = new Intent( ACTION_VIEW, uri);

    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    if (activities.size() > 0)
    {
        startActivity(intent);
    }
    else
    {
        Toast.makeText(getApplicationContext(),
                       "ERROR - no application to display a web page",
                       Toast.LENGTH_SHORT).show();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Robolectric进行单元测试,但我无法验证这种方法.具体来说,getPackageManager()始终返回null.我怎么能影子PackageManager呢?我尝试创建一个ShadowPackageManager并调用bindShadowClass,但我的代码都没有被执行 - getPackageManager()总是返回null.我也尝试了Shadow the Application上下文并返回一个具体的StubPackageManager,但得到了相同的结果.也许我一直在寻找/盯着太长时间 - 有没有更好的方法对这种方法进行单元测试?

ale*_*ull 9

我正在使用Robolectric 2.3.如其他答案所述,getPackageManager()不返回null,但shadowApplication.setPackageManager不再存在.

既然你不能模拟PackageManager,你就不能给它一个Intents要解决的列表.幸运的是,Robolectric的PackageManager子类,RobolectricPackageManager可以让你在没有模拟的情况下添加这些意图:

RobolectricPackageManager rpm = (RobolectricPackageManager)Robolectric.application.getPackageManager();
rpm.addResolveInfoForIntent(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS), new ResolveInfo());
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,**Robolectric 3.4** `RobolectricPackageManager` 已更改为 `ShadowPackageManager pm = shadowOf(RuntimeEnvironment.application.getPackageManager());` (2认同)

Jan*_*kel 7

出于某种原因,您需要在应用程序上手动设置shadow packagemanager.创建自定义测试运行器(通过扩展RobolectricTestRunner)并覆盖setApplicationState方法:

public class MyTestRunner extends RobolectricTestRunner {   
  @Override
  public void setupApplicationstate(RobolectricConfig robolectricConfig) {
     super.setupApplicationState(robolectricConfig);
     ShadowApplication shadowApplication = shadowOf(Robolectric.application);
     shadowApplication.setPackageName(robolectricConfig.getPackageName());
     shadowApplication.setPackageManager(new RobolectricPackageManager(Robolectric.application, robolectricConfig));
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在测试中指定您要使用自己的测试运行器:

@RunWith(MyTestRunner.class)
public class MyTest { ... }
Run Code Online (Sandbox Code Playgroud)