由于这个问题和答案帮助了我好几年,我想我会添加我自己的建议,那就是assert
阅读dataPosition()
结束时的 the 与写作结束时的相同。基于Xilconic 的回答:
@Test
public void testTestClassParcelable(){
TestClass test = new TestClass();
// Obtain a Parcel object and write the parcelable object to it:
Parcel parcel = Parcel.obtain();
test.writeToParcel(parcel, 0);
//>>>>> Record dataPosition
int eop = parcel.dataPosition();
// After you're done with writing, you need to reset the parcel for reading:
parcel.setDataPosition(0);
// Reconstruct object from parcel and asserts:
TestClass createdFromParcel = TestClass.CREATOR.createFromParcel(parcel);
assertEquals(test, createdFromParcel);
//>>>>> Verify dataPosition
assertEquals(eop, parcel.dataPosition());
}
背景:这是在花了(令人尴尬的)时间调试一个 bad Parcelable
. 就我而言,writeToParcel
是从一个中等复杂的对象图中的一个对象编写一个重复的字段。因此,随后的对象被错误地读取,给出了误导性的异常,并且在使用特定行为不端的对象的测试中没有错误。
追踪起来很痛苦,然后我意识到检查dataPosition
会更快地查明问题,因为我对内部对象和主容器进行了测试。
Kotlin:因为我在 Kotlin 工作,所以有点 lambda 和具体化魔法:
class ParcelWrap<T>(val value: T)
val <T> T.parcel: ParcelWrap<T> get() = ParcelWrap(this)
inline fun <reified T: Parcelable> ParcelWrap<T>.test(
flags: Int = 0,
classLoader: ClassLoader = T::class.java.classLoader,
checks: (T) -> Unit
): T {
// Create the parcel
val parcel: Parcel = Parcel.obtain()
parcel.writeParcelable(this.value, flags)
// Record dataPosition
val eop = parcel.dataPosition()
// Reset the parcel
parcel.setDataPosition(0)
// Read from the parcel
val newObject = parcel.readParcelable<T>(classLoader)
// Perform the checks provided in the lambda
checks(newObject)
// Verify dataPosition
assertEquals("writeToParcel wrote too much data or read didn't finish reading", eop, parcel.dataPosition())
return newObject
}
我现在可以很容易地按照这些思路进行测试,如果有一个完整且可靠的equals()
:
testObject.parcel.test { assertEquals(testObject, it) }
请注意,避免使用此答案.parcel.test
重新指定泛型类型参数。
或者,对于更复杂的断言:
testObject.parcel.test {
assertEquals(123, it.id)
assertEquals("dewey", it.name)
// ...
}