单元测试:调用 Notification.setLatestEventInfo() 时出现 NoSuchMethodError

Unit testing: NoSuchMethodError while calling Notification.setLatestEventInfo()

Feel free to improve the title I'm a little uncreative in this special case.

我正在实施一个检查通知的单元测试,我知道这几乎不可能,但我想检查一下我能将它自动化到什么程度。

我无法测试这行简单的代码:

Notification test = new NotificationCompat.Builder(context).build();

原因很愚蠢,也很简单。此处的这段代码将在内部执行:

public Notification build(Builder b, BuilderExtender extender) {
    Notification result = b.mNotification;
    result.setLatestEventInfo(b.mContext, b.mContentTitle,
            b.mContentText, b.mContentIntent);
    [...]

我遇到了这个异常:

Caused by: java.lang.NoSuchMethodError: android.app.Notification.setLatestEventInfo(Landroid/content/Context;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;)V
    at android.support.v4.app.NotificationCompat$NotificationCompatImplBase.build(NotificationCompat.java:479)
    at android.support.v4.app.NotificationCompat$Builder.build(NotificationCompat.java:1561)

不难猜测 Google 家伙在这里调用了一个方法,该方法已在 Android Marshmallow SDK 中删除(或更恰当地用 @hide 注释)。我已经确认 call 缺少最新的文档,但它是在 API 1 AFIK.

中引入的

我该如何解决这个问题?

我尝试过但卡住了的事情:

解决方案比预期的要容易。我错过了默认情况下 Build.VERSION.SDK_INT 的值 0 因为它无法读取实际值。因此支持库仅在存在此方法的平台上调用它。

this answer 的帮助下。我只需要添加这段代码:

setFinalStatic(Build.VERSION.class.getDeclaredField("SDK_INT"), 23);

我的代码有效。
好吧,它仍然在其他地方崩溃,但已创建通知。哇哦!

实际函数:

public static void setFinalStatic(Field field, Object newValue) throws IllegalAccessException, NoSuchFieldException
{
    field.setAccessible(true);
    // remove final modifier from field
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}