Dal momento che questa domanda e le risposte mi ha aiutato diversi anni giù la linea, ho pensato di aggiungere la mia proposta, che sarebbe quello di assert
che il dataPosition()
alla fine del la lettura era la stessa della fine della scrittura. Sulla Xilconic's answer:
@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());
}
Background: Questo è venuto da me dopo aver trascorso un importo (imbarazzante) di tempo debug di un cattivo Parcelable
. Nel mio caso, writeToParcel
stava scrivendo un campo duplicato da un oggetto all'interno di un grafico di oggetto moderatamente complesso. Pertanto gli oggetti successivi a sono stati letti in modo errato, fornendo eccezioni fuorvianti e nessun errore nei test con l'oggetto specifico che si comporta male.
E 'stato un dolore da rintracciare, e poi mi sono reso conto che il controllo di dataPosition
avrebbe individuato il problema più velocemente poiché ho eseguito test su oggetti interni e sul contenitore principale.
Kotlin: Dal momento che sto lavorando in Kotlin, un po 'di lambda e magia reificare:
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
}
ora posso test molto facilmente in questo senso, se v'è un completo ed affidabile equals()
:
testObject.parcel.test { assertEquals(testObject, it) }
Annotare il .parcel.test
evita di dover specificare nuovamente parametro di tipo generico utilizzando 012.324.924,439 mila.
Oppure, per ulteriori asserzioni complesse:
testObject.parcel.test {
assertEquals(123, it.id)
assertEquals("dewey", it.name)
// ...
}
Se uno dei nostri anwers come soluzione al vostro problema, si prega di contrassegnare come risposta accettata :) – Xilconic