11

通知がカスタムサウンドをアセットから再生できるかどうかを単体テストからテストしたいと思います。 このテストでは何も検証するつもりはないので、私は主なアプリケーションコードを乱雑にすることなく、機能を実証するための素早い方法として書きました。InstrumentationTestCaseから通知を作成する

だからテストプロジェクトでは、/res/rawの中にwavファイルを追加しました。

Uri path = Uri.parse("android.resource://<main app package name>/testsound.wav"); 

このURLは、私が今まで読んできた質問に従って動作するはずです。それが動作すると仮定しましょう。

メインプロジェクトの/res/rawフォルダにテストwavファイルを含めたくないので、テストプロジェクト1には、ユニットテストをInstrumentationTestCaseから拡張して、テストプロジェクト

ここでは、コードです:

NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getContext()); 
    ... 
    builder.setSound(path, AudioManager.STREAM_NOTIFICATION); 
    ... 
    NotificationManager notificationManager = (NotificationManager) getInstrumentation().getContext().getSystemService(Context.NOTIFICATION_SERVICE); 
    notificationManager.notify(NOTIFICATION_ID, builder.build()); 

notify呼び出しは次の例外投げている:私はダウンNotificationManagerServiceクラスにこの例外を追跡してきた

java.lang.SecurityException: Calling uid 10198 gave package <main app package name> which is owned by uid 10199 
    at android.os.Parcel.readException(Parcel.java:1540) 
    at android.os.Parcel.readException(Parcel.java:1493) 
    at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:611) 
    at android.app.NotificationManager.notify(NotificationManager.java:187) 
    at android.app.NotificationManager.notify(NotificationManager.java:140) 
    ... 
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1873) 

を:

void checkCallerIsSystemOrSameApp(String pkg) { 
     int uid = Binder.getCallingUid(); 
     if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { 
      return; 
     } 
     try { 
      ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
        pkg, 0, UserHandle.getCallingUserId()); 
      if (!UserHandle.isSameApp(ai.uid, uid)) { 
       throw new SecurityException("Calling uid " + uid + " gave package" 
         + pkg + " which is owned by uid " + ai.uid); 
      } 
     } catch (RemoteException re) { 
      throw new SecurityException("Unknown package " + pkg + "\n" + re); 
     } 
    } 

は、どうやら例外はカスタムとは関係ない私たちがInstrumentationTestCaseからの通知を作成しているという事実とは対照的です。

これをテストする方法はありますか?私は過去にAndroidTestCaseからの通知を作成したことを覚えていますが、それを行うとテストwavファイルにアクセスすることはできません。私はwavでjarファイルを作成し、jarをテストプロジェクトのlibフォルダに落とすことができますが、これはファイルを隠してしまい、他のプログラマが将来置き換える必要がある場合は、探しているのが難しいかもしれません。

答えて

0

AndroidTestCaseから音が出る方法を考えました。 wavファイルがテストプロジェクトのrawフォルダに追加され、意図したとおりにメインプロジェクトに含まれていませんでした。

通知用のURLは、このようなものだった:

Uri path = Uri.parse("android.resource://<test project package name>/" + R.raw.air_horn); 

そして、次のようにビルダーが得られた:

NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext()); 
2

実際、私は疑問に困惑しています。だから私は小規模な計装テストを書いた。

私はAPI 23でしか実行できないテストをマークしましたが(getActiveNotificationsは以前は利用できないようです)、古いAPIでもうまく機能します。

トリックはgetContext()の代わりにgetTargetContext()を使用することです:それは魔法のように動作

public final class MainActivityTest extends ActivityUnitTestCase<MainActivity> { 

    public MainActivityTest() { 
     super(MainActivity.class); 
    } 

    @TargetApi(Build.VERSION_CODES.M) 
    public void testSendNotification() { 
     final NotificationManager manager = (NotificationManager) getInstrumentation().getTargetContext().getSystemService(Context.NOTIFICATION_SERVICE); 

     manager.cancel(42); 
     assertEquals(0, manager.getActiveNotifications().length); 

     final NotificationCompat.Builder builder = new NotificationCompat.Builder(getInstrumentation().getTargetContext()); 
     builder.setContentTitle("Notification test") 
       .setAutoCancel(true) 
       .setContentText("Hello, Mister Smith") 
       .setSmallIcon(R.drawable.ic_launcher_notification); 

     manager.notify(42, builder.build()); 

     assertEquals(1, manager.getActiveNotifications().length); 
    } 
} 

enter image description here

希望は、それが役立ちます。

+0

うん、これは動作します。 wavファイルは期待どおりに再生されます。唯一の欠点は、メインプロジェクトからアクティビティが必要なことです。 –

+0

@MisterSmithでも、ユニットテストではなく、**計装テスト**について質問しています。あなたの答えはあなたが求める質問を反映していません。 –

+0

はい、申し訳ありません。 [この質問](http://stackoverflow.com/questions/9249751/accessing-resources-in-an-android-で説明したように、私は、テストプロジェクトのリソースにアクセスするために、私は機器を使用していたと仮定しました。テストプロジェクト))。しかし、それは通常の単体テストから動作することが判明しました。とにかくありがとう。 –

関連する問題