Android: 在服务中测试 MediaPlayer

Android: Testing MediaPlayer inside a service

在我的应用程序中,有一项服务的工作是在启动时 play/stop 播放音频。为此,我正在使用 MediaPlayer

服务运行良好,现在我正在为其编写测试。 我正在使用 Robolectric 的 buildService 方法来创建服务。 问题是 mediaplayer 在我的例子中总是出现空值。 这是我的服务的 onStartCommand 方法:

@Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    if (ACTION_START.equals(intent.getAction())) {
      try {
        mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.holdmusic);
      } catch (Exception e) {
        Log.e(TAG, "not able to prepare media player", e);
        Toast.makeText(this, R.string.not_able_prepare_media_player, Toast.LENGTH_SHORT).show();
        stopSelf();
        return START_NOT_STICKY;
      }
      notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

      mediaPlayer.setOnCompletionListener(mediaPlayer -> onStop()); // mediaplayer always comes out to be null here in my test
      mediaPlayer.start();
      mediaSession = new MediaSession(getApplicationContext(), getString(R.string.app_name));
      showNotification();
      return START_STICKY;
    } else if (ACTION_STOP.equals(intent.getAction())) {
      onStop();
      return START_NOT_STICKY;
    } else {
      // called with unknown action, should not happen
      stopSelf();
      return START_NOT_STICKY;
    }
  }

这是我的测试:

@Test
  public void testActionStart() {
    Intent serviceIntent =
        new Intent(ApplicationProvider.getApplicationContext(), MediaPlayerService.class);
    serviceIntent.setAction(MediaPlayerService.ACTION_START);

    MediaPlayerService service =
        Robolectric.buildService(MediaPlayerService.class, serviceIntent)
            .create()
            .startCommand(0, 0)
            .get();
    ShadowService shadowService = Shadow.extract(service);

    assertThat(service.isPlaying()).isTrue();
    assertThat(shadowService.getLastForegroundNotification()).isNotNull();
  }

谁能帮我理解为什么 mediaplayer 结果为空。我想可能是因为它使用了 robolectric 环境中不可用的本机方法。如果是这样,测试服务行为的最佳方法是什么?

经过 https://github.com/robolectric/robolectric/issues/3855 和调试一段时间后,我意识到我们必须手动填充 ShadowMediaPlayer 中的 MediaInfo 对象才能工作。

这是我所做的(现在效果很好):

在实例化播放器之前添加了这一行:

ShadowMediaPlayer.addMediaInfo(
        DataSource.toDataSource(
            "android.resource://"
                + getApplicationContext().getPackageName()
                + "/"
                + <resource id of audio file>),
        new MediaInfo(17, 0));