2010-01-19 15 views
50

Estoy escribiendo mi primer back-end de base de datos de Android y estoy luchando para probar la creación de mi base de datos.Android Unit Tests que requieren contexto

Actualmente el problema que estoy encontrando es obtener un objeto de contexto válido para pasar a mi implementación de SQLiteOpenHelper. ¿Hay alguna manera de obtener un objeto Contexto en una clase que extienda TestCase? La solución que he pensado es crear una instancia de una actividad en el método de configuración de mi TestCase y luego asignar el contexto de esa actividad a una variable de campo a la que pueden acceder mis métodos de prueba ... pero parece que debería haber una manera más fácil.

¡Gracias por su contribución!

Macy

Respuesta

37

Es posible que trate de cambiar a AndroidTestCase. Al mirar los documentos, parece que debería poder proporcionarle un contexto válido para pasar a SQLiteOpenHelper.

Nota: Tenga en cuenta que probablemente tenga que realizar la configuración de sus pruebas en un "Android Test Project" en Eclipse, ya que las pruebas intentarán ejecutarse en el emulador (o dispositivo real).

+0

Gracias Erich, es definitivamente el camino correcto a seguir. –

+0

al extender AndroidTestCase y luego se devuelve 'this.getContext()', 'null'. ¿Es así como se supone que funciona? Esperaba que se devolviera un contexto enriquecido que funcionaría con SQLite – cdaringe

+3

AndroidTestCase ahora está en desuso, y se recomienda utilizar InstrumentationRegistry en su lugar. –

1

Debe utilizar ApplicationTestCase o ServiceTestCase.

4

El uso del método AndroidTestCase:getContext() solo proporciona un contexto de stub en mi experiencia. Para mis pruebas, estoy usando una actividad vacía en mi aplicación principal y obtengo el Context a través de eso. También extiendo la clase suite de prueba con la clase ActivityInstrumentationTestCase2. Parece funcionar para mi.

public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity> 
    EmptyActivity activity; 
    Context mContext = null; 
    ... 
    @Before 
    public void setUp() { 
     activity = getActivity(); 
     mContext = activity; 
    } 
    ... //tests to follow 
} 

¿Qué hace el resto?

1

Extender AndroidTestCase y llamar a AndroidTestCase: getContext() me ha funcionado para obtener Contexto y usarlo con SQLiteDatabase.

La única pega es que la base de datos se crea y/o usos será el mismo que el utilizado por la aplicación de producción por lo que probablemente tendrá que usar un nombre de archivo diferente para ambos

por ejemplo.

public static final String NOTES_DB  = "notestore.db"; 
    public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db"; 
1

Puede derivar de MockContext y regresar por ejemplo, un MockResources en getResources(), una válida ContentResolver en getContentResolver(), etc, que permite, con un poco de dolor, algunos equipo realiza un test.

La alternativa es ejecutar, por ejemplo, Robolectric, que simula todo un sistema operativo Android. Esos serían para pruebas del sistema: es mucho más lento de ejecutar.

-1

La solución alternativa es evitar el uso de ApplicationTestCase o AndroidTestCase o cualquier otra clase que dependa de Context. El punto es que no hay necesidad de probar SQLite o ORM marco de lo que podría crear la interfaz con CRUD métodos básicos:

public interface UsersManager{ 
    User createUser(String userId); 
    User getUser(String userId); 
    boolean updateUser(User user); 
    boolean deleteUser(User user); 
} 

e implementar dos versiones: una para las pruebas y otro para el tiempo de ejecución de producción.Versión para las pruebas podría ser implementado fácilmente con HashMap:

public class TestUsersManager implements UsersManager{ 

    private HashMap<String, User> users = new HashMap(); 

    public User createUser(String userId){ 
    User result = new User(userId); 
    users.put(userId, user); 
    return result; 
    } 
    //... other methods 
} 

Funciona rápido (sin disco IO en caso de SQLite) y no tiene dependencias externas. Por cierto, este es también un nivel adicional de abstracción: para el código de producción, puede cambiar fácilmente entre los marcos ORM, por ejemplo.

14

Si está ejecutando sus pruebas con AndroidJUnit4 puede utilizar InstrumentationRegistry métodos para conseguir un Contexto:

InstrumentationRegistry.getTargetContext() - proporciona la aplicación Context de la aplicación de destino;

InstrumentationRegistry.getContext() - proporciona el Context del paquete de esta Instrumentación;

+1

¿De qué dependencia proviene AndroidJUnit4.class? – Ewoks

+3

ídem en la necesidad de un ejemplo más completo. – StarWind0

0

First Create Test Class en (androidTest).

Ahora usa siguiente código:

public class YourDBTest extends InstrumentationTestCase { 

private DBContracts.DatabaseHelper db; 
private RenamingDelegatingContext context; 

@Override 
public void setUp() throws Exception { 
    super.setUp(); 
    context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_"); 
    db = new DBContracts.DatabaseHelper(context); 
} 

@Override 
public void tearDown() throws Exception { 
    db.close(); 
    super.tearDown(); 
} 

@Test 
public void test1() throws Exception { 
    // here is your context 
    context = context; 
}}