【问题标题】:Testing parcel read write with mocked dependencies使用模拟依赖项测试包裹读写
【发布时间】:2018-01-19 17:57:42
【问题描述】:

我正在尝试在我制作的一些模型类中测试我的包裹实现,并使用模拟的依赖项。但是,每次我使用所述模拟依赖项对其进行初始化,然后将其写入和读取到一个宗地时,我都会为我的类 Alarm 获得一个 Class not found when unmarshalling: Interval_Proxy 异常,并带有模拟依赖项间隔。

问题可能是在我的包裹读取实现中,我在读取该特定依赖项时使用了一个 Interval 类加载器,即使模拟将它变成了一个 Interval_Proxy 类型,但我真的不知道。

任何人都可以对此有所了解吗?

我的测试:

UUID id = UUID.fromString("feb33f17-8512-4416-b376-84fd0bb603ef");
Date date = mock(Date.class);
Interval interval = mock(Interval.class);
Prescription prescription = mock(Prescription.class);

Alarm alarm = new Alarm(id, date, interval, prescription, false, false);

Parcel parcel = Parcel.obtain();
alarm.writeToParcel(parcel, 0);
parcel.setDataPosition(0);

Alarm parceledAlarm = Alarm.CREATOR.createFromParcel(parcel);

assertThat(alarm.getId(), is(id));
assertThat(alarm.getDate(), is(date));
assertThat(alarm.getInterval(), is(interval));
assertThat(alarm.getPrescription(), is(prescription));
assertThat(alarm.isDismissed(), is(false));
assertThat(alarm.isDismissed(), is(false));

assertThat(alarm, is(parceledAlarm));

我的报警包裹读写:

protected Alarm(Parcel in) {
    id = ((ParcelUuid) in.readParcelable(ParcelUuid.class.getClassLoader())).getUuid();
    checked = in.readByte() != 0;
    dismissed = in.readByte() != 0;
    interval = in.readParcelable(Interval.class.getClassLoader());
    prescription = in.readParcelable(Prescription.class.getClassLoader());
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeParcelable(new ParcelUuid(id), flags);
    dest.writeByte((byte) (checked ? 1 : 0));
    dest.writeByte((byte) (dismissed ? 1 : 0));
    dest.writeParcelable(interval, flags);
    dest.writeParcelable(prescription, flags);
}

抛出的异常:

E/Parcel: Class not found when unmarshalling: Interval_Proxy
      java.lang.ClassNotFoundException: Interval_Proxy
          at java.lang.Class.classForName(Native Method)
          at java.lang.Class.forName(Class.java:453)
          at android.os.Parcel.readParcelableCreator(Parcel.java:2818)
          at android.os.Parcel.readParcelable(Parcel.java:2772)
          at com.rasive.pillreminder.models.Alarm.<init>(Alarm.java:46)
          at com.rasive.pillreminder.models.Alarm$1.createFromParcel(Alarm.java:67)
          at com.rasive.pillreminder.models.Alarm$1.createFromParcel(Alarm.java:64)
          at com.rasive.pillreminder.AlarmTest_Parcelable.createParcel(AlarmTest_Parcelable.java:37)
          at java.lang.reflect.Method.invoke(Native Method)
          at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
          at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
          at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
          at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
          at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
          at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
          at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
          at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
          at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
          at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
          at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
          at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
          at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
          at org.junit.runners.Suite.runChild(Suite.java:128)
          at org.junit.runners.Suite.runChild(Suite.java:27)
          at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
          at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
          at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
          at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
          at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
          at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
          at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
          at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
          at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
          at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
          at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2074)
       Caused by: java.lang.ClassNotFoundException: Didn't find class "Interval_Proxy" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.rasive.pill_reminder.test-y_qRLspX6rV77YcK6XvlOQ==/base.apk", zip file "/data/app/com.rasive.pill_reminder-x2CBSuyy8_Rbcx9mOQPmSg==/base.apk"],nativeLibraryDirectories=[/data/app/com.rasive.pill_reminder.test-y_qRLspX6rV77YcK6XvlOQ==/lib/x86, /data/app/com.rasive.pill_reminder-x2CBSuyy8_Rbcx9mOQPmSg==/lib/x86, /system/lib, /vendor/lib]]

【问题讨论】:

    标签: android unit-testing testing mockito parcel


    【解决方案1】:

    这完全是在黑暗中拍摄,但您可以尝试在 Alarm 类中以不同的方式写入/读取 Parcelable 字段。我一般是这样做的:

    public static void writeParcelable(Parcel dest, Parcelable p, int flags) {
        if (p != null) {
            dest.writeInt(1);
            p.writeToParcel(dest, flags);
        }
        else {
            dest.writeInt(0);
        }
    }
    
    public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<? extends T> creator) {
        if (in.readInt() != 0) {
            return creator.createFromParcel(in);
        }
        else {
            return null;
        }
    }
    

    然后,您将您的 Alarm 类更改如下:

    protected Alarm(Parcel in) {
        ParcelUuid parcelUuid = Utils.readParcelable(in, ParcelUuid.CREATOR);
        id = parcelUuid.getUuid();
        checked = in.readByte() != 0;
        dismissed = in.readByte() != 0;
        interval = Utils.readParcelable(in, Interval.CREATOR);
        prescription = Utils.readParcelable(in, Prescription.CREATOR);
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Utils.writeParcelable(dest, new ParcelUuid(id), flags);
        dest.writeByte((byte) (checked ? 1 : 0));
        dest.writeByte((byte) (dismissed ? 1 : 0));
        Utils.writeParcelable(dest, interval, flags);
        Utils.writeParcelable(dest, prescription, flags);
    }
    

    这完全绕过了类加载器的使用,所以我希望它能帮助您解决问题。不相关,但它具有编译时类型检查的额外好处(如果你传递了错误的CREATOR,你会得到一个错误)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多