使用模拟依赖项测试parcel读写

时间:2018-01-19 17:57:42

标签: android unit-testing testing mockito parcel

我正在尝试在我使用模拟依赖项创建的某个模型类中测试我的parcel实现。但是,每次我使用所述模拟的依赖项初始化它,然后写入并读取它到一个包裹时,我的类警报会得到一个Class not found when unmarshalling: Interval_Proxy异常,并使用模拟的依赖Interval。

问题可能是在我的parcel读取实现中,我在读取特定依赖项时使用Interval类加载器,即使mock使其成为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]]

1 个答案:

答案 0 :(得分:0)

这是黑暗中的总镜头,但您可以尝试在Parcelable课程中以不同方式书写/阅读Alarm字段。我通常这样做:

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,你将收到错误)。