2012-10-10 35 views
28

Làm thế nào để bạn kiểm tra đơn vị Bưu kiện? Tôi tạo ra một lớp Parcelable, và viết bài kiểm tra đơn vị nàyThử nghiệm Đơn vị Android: Gói/Bưu kiện

TestClass test = new TestClass(); 
Bundle bundle = new Bundle(); 
bundle.putParcelable("test", test); 

TestClass testAfter = bundle.getParcelable("test"); 
assertEquals(testAfter.getStuff(), event1.getStuff()); 

tôi cố tình cố gắng không kiểm tra bằng cách trả lại null trong createFromParcel(), nhưng có vẻ như để thành công. Có vẻ như nó không nhận được bưu kiện cho đến khi nó cần thiết. Làm thế nào để buộc các Bundle để ..bundle?

+1

Nếu một trong hai anwers của chúng tôi như một giải pháp cho vấn đề của bạn, xin vui lòng đánh dấu chúng là một câu trả lời chấp nhận :) – Xilconic

Trả lời

81

Tôi đã tìm thấy link này cho thấy làm thế nào bạn có thể đơn vị kiểm tra một đối tượng parcelable: http://stuffikeepforgettinghowtodo.blogspot.nl/2009/02/unit-test-your-custom-parcelable.html

Bạn có thể thực sự bỏ qua Bundle nếu bạn don 't thực sự cần phải bao gồm nó như zorch đã làm đề nghị của mình. Sau đó bạn sẽ nhận được một cái gì đó như thế này:

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); 

    // 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); 
} 
+3

'parcel.setDataPosition (0);' là bí mật. Cảm ơn – scorpiodawg

+0

Làm việc cho tôi. Cảm ơn!. – ernestkamara

+0

Không có cơ hội để làm việc! Bạn sẽ luôn nhận được '' 'BadParcelableException'''. – ddmytrenko

16

Bạn có thể làm điều đó bằng cách này:

//Create parcelable object and put to Bundle 
    Question q = new Question(questionId, surveyServerId, title, type, answers); 
    Bundle b = new Bundle(); 
    b.putParcelable("someTag", q); 

//Save bundle to parcel 
    Parcel parcel = Parcel.obtain(); 
    b.writeToParcel(parcel, 0); 

//Extract bundle from parcel 
    parcel.setDataPosition(0); 
    Bundle b2 = parcel.readBundle(); 
    b2.setClassLoader(Question.class.getClassLoader()); 
    Question q2 = b2.getParcelable("someTag"); 

//Check that objects are not same and test that objects are equal 
    assertFalse("Bundle is the same", b2 == b); 
    assertFalse("Question is the same", q2 == q); 
    assertTrue("Questions aren't equal", q2.equals(q)); 
+0

Các bạn đã thử với loại khẳng định: 'Khẳng định .assertTrue (EqualsBuilder.reflectionEquals (q2, q)); '? Tôi hỏi vì trong trường hợp bạn có một danh sách 'List = new ArrayList 'như một trường trong mô hình dữ liệu' Question.java' của bạn thì mã bạn viết nó không hoạt động.Nếu bạn có 'ArrayList = new ArrayList ' nó hoạt động. Bạn có biết làm sao để sửa cái này không? –

1

Kể từ khi câu hỏi này và câu trả lời giúp tôi vài năm xuống dòng, tôi nghĩ rằng tôi muốn thêm gợi ý của riêng tôi, mà sẽ được assert rằng dataPosition() ở phần cuối của đọc cũng giống như ở cuối bài viết. Xây dựng trên 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()); 
} 

Bối cảnh: này đến với tôi sau khi trải qua một (xấu hổ) số lượng thời gian gỡ một xấu Parcelable. Trong trường hợp của tôi, writeToParcel đã viết một trường trùng lặp từ một đối tượng trong một biểu đồ đối tượng phức tạp vừa phải. Do đó, các đối tượng sau được đọc không chính xác, đưa ra các ngoại lệ gây hiểu lầm và không có lỗi nào trong các thử nghiệm với đối tượng bị lỗi cụ thể.

Đó là một nỗi đau để theo dõi, và sau đó tôi nhận ra việc kiểm tra dataPosition sẽ xác định được vấn đề nhanh hơn vì tôi có các thử nghiệm đối tượng bên trong cũng như vùng chứa chính.


Kotlin: Kể từ khi tôi đang làm việc trong Kotlin, một lambda nhỏ và reifying kỳ diệu:

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 
} 

bây giờ tôi có thể kiểm tra rất dễ dàng cùng những dòng này, nếu có một đầy đủ và đáng tin cậy equals() :

testObject.parcel.test { assertEquals(testObject, it) } 

Lưu ý rằng .parcel.test tránh phải chỉ định lại thông số loại chung sử dụng this answer.

Hoặc, để biết thêm khẳng định phức tạp:

testObject.parcel.test { 
    assertEquals(123, it.id) 
    assertEquals("dewey", it.name) 
    // ... 
}