2013-01-06 34 views
10

Tôi đang viết một ApplicationTestCase Android (ví dụ về TemperatureConverterApplicationTests được tìm thấy trong Hướng dẫn kiểm tra ứng dụng Android bởi Diego T. Milano trên trang 171). Ví dụ này được viết cho Android 2.3 và nó dường như không hoạt động cho Android 4. Bạn không cần phải biết cuốn sách để hiểu vấn đề như tôi đã đơn giản hóa nó.AssertionFailedError trong ApplicationTestCase.createApplication() trong các phiên bản Android mới hơn khi sử dụng MockContext

này hoạt động tốt với Android 2.3.3 (API 10):

setContext(new MockContext()); 
createApplication(); 

[Để được chính xác một UnsupportedOperationException được ném bởi vì getPackageName() không được thực hiện. Nhưng điều này là bình thường và có thể được giải quyết bằng cách sử dụng một lớp con của MockContext() thực hiện getPackageName() và getSharedPreferences(). Điều này không liên quan vì vấn đề vẫn tồn tại ngay cả sau khi thực hiện việc này.]

Vấn đề là với Android 4.1.2 (API 16) nó không hoạt động. Tôi nhận được một AssertionFailedError rằng thông qua một số gỡ lỗi tôi phát hiện ra là do một ClassCastException được ném trên dòng 100 của ApplicationTestCase.

mApplication = (T) Instrumentation.newApplication(mApplicationClass, getContext()); 

Các ClassCastException thông điệp là:

java.lang.ClassCastException: android.test.mock.MockContext cannot be cast to android.app.ContextImpl 

Bất kỳ gợi ý tại sao điều này xảy ra và làm thế nào nó có thể tránh được?

EDIT: Câu hỏi liên quan: Android ApplicationTestCase using a MockContext

+1

Tôi gặp vấn đề tương tự. Nó hoạt động tốt bằng cách sử dụng một lớp mở rộng RenamingDelegatingContext nhưng không mở rộng MockContext. Tôi đã đăng một câu hỏi tương tự ở đây http://stackoverflow.com/questions/14205451/android-applicationtestcase-using-a-mockcontext. Tôi sẽ trả lời nếu tôi tìm thấy bất cứ điều gì. – odiggity

Trả lời

0

Phương pháp Instrumentation.newApplication() sẽ trả về một đối tượng Application. Bạn đang cố gắng truyền nó tới bất cứ điều gì T. Nếu T không phải là siêu hạng hoặc lớp phụ của Application, bạn sẽ nhận được ClassCastException. Trong Java, bạn chỉ có thể truyền một đối tượng tới một thứ gì đó là một lớp siêu hoặc một lớp con của đối tượng đó. Nếu không thì ngoại lệ sẽ bị ném.

VÍ DỤ:

Object x = new Integer(0); 
System.out.println((String)x); 

này sẽ ném một ClassCastException trên dòng thứ hai bởi vì bạn đang cố gắng để cast x (một đối tượng Integer) vào một String. Bởi vì StringInteger không phải là các lớp phụ hoặc siêu của nhau.

1

Tôi cũng nhận được hành vi này. Tôi đã làm việc xung quanh nó bằng cách mở rộng ContextWrapper:

public class RenamingMockContext extends RenamingDelegatingContext 
{ 
    private static final String PREFIX = "test."; 

    public RenamingMockContext(Context context) 
    { 
     super(new ContextWrapper(context), PREFIX); 
    } 

    @Override 
    public String getPackageName() 
    { 
     return PREFIX + super.getPackageName(); 
    } 
} 
Các vấn đề liên quan