2013-01-06 20 views
10

Sto scrivendo un ApplicationTestCase Android (TemperatureConverterApplicationTests esempio si trovano in Android Application Testing Guida da Diego T. Milano a pagina 171). L'esempio è stato scritto per Android 2.3 e non sembra funzionare per Android 4. Non è necessario conoscere il libro per capire il problema in quanto l'ho semplificato.AssertionFailedError in ApplicationTestCase.createApplication() nelle versioni più recenti di Android quando si utilizza MockContext

Questo funziona bene con Android 2.3.3 (API 10):

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

[Per essere precisi un UnsupportedOperationException è gettato perché getPackageName() non è implementata. Ma questo è normale e può essere risolto utilizzando una sottoclasse di MockContext() che implementa getPackageName() e getSharedPreferences(). Questo non è pertinente perché il problema esiste ancora, anche dopo aver fatto questo.]

Il problema è che con Android 4.1.2 (API 16) non funziona. Ricevo un AssertionFailedError che tramite alcuni debug ho scoperto essere dovuto a una ClassCastException lanciata sulla linea 100 di ApplicationTestCase.

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

Il ClassCastException messaggio è:

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

Eventuali suggerimenti perché questo accade e come può essere evitato?

EDIT: questione connessa: Android ApplicationTestCase using a MockContext

+1

Sto avendo lo stesso identico problema. Funziona bene usando una classe che estende RenamingDelegatingContext ma non un MockContext. Ho postato una domanda simile qui http://stackoverflow.com/questions/14205451/android-applicationtestcase-using-a-mockcontext. Risponderò se trovo qualcosa. – odiggity

risposta

0

Il metodo Instrumentation.newApplication() restituirà un oggetto Application. Stai provando a lanciarlo su qualsiasi cosa sia T. Se T non è una super classe o sottoclasse di Application, riceverai uno ClassCastException. In Java è possibile eseguire il cast di un oggetto su qualcosa che è una super classe o sottoclasse di tale oggetto. Se non lo è, verrà lanciata l'eccezione.

PER ESEMPIO:

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

Questo lancerà una ClassCastException sulla seconda linea perché il tentativo di lanciare x (un Integer oggetto) ad un String. Perché uno String e Integer non sono classi secondarie o super l'uno dell'altro.

1

Ottengo anche questo comportamento. Ho lavorato intorno estendendo 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(); 
    } 
}