database - room - Pruebas unitarias de Android que requieren contexto
room android database (8)
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.
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 tu contribución!
Macy
Debe usar ApplicationTestCase o ServiceTestCase.
Extendiendo AndroidTestCase y llamando a AndroidTestCase: getContext () me ha funcionado para obtener Contexto y usarlo con SQLiteDatabase.
El único inconveniente es que la base de datos que crea y / o utiliza será la misma que la utilizada por la aplicación de producción, por lo que es probable que desee utilizar un nombre de archivo diferente para ambos
p.ej.
public static final String NOTES_DB = "notestore.db";
public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db";
Primero crea la clase de prueba debajo (prueba de android).
Ahora usa el 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;
}}
Puede derivar de MockContext y devolver, por ejemplo, MockResources en getResources()
, un ContentResolver válido en getContentResolver()
, etc. Eso permite, con cierto dolor, algunas pruebas de unidad .
La alternativa es ejecutar, por ejemplo, Robolectric que simula todo un sistema operativo Android. Esos serían para las pruebas del sistema : es mucho más lento para ejecutar.
Puede intentar cambiar a AndroidTestCase . Al mirar los documentos, parece que debería poder proporcionarle un contexto válido para pasar a SQLiteOpenHelper.
Editar: tenga en cuenta que probablemente tenga que configurar sus pruebas en un "Android Test Project" en Eclipse, ya que las pruebas intentarán ejecutarse en el emulador (o dispositivo real).
Si está ejecutando sus pruebas con AndroidJUnit4
, puede usar los métodos InstrumentationRegistry
para obtener un contexto:
InstrumentationRegistry.getTargetContext()
: proporciona la aplicación Context
de la aplicación de destino.
InstrumentationRegistry.getContext()
: proporciona el Context
del paquete de este Instrumentación.
Una 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 el marco SQLite
o ORM
para que pueda crear una interfaz con los métodos CRUD
básicos:
public interface UsersManager{
User createUser(String userId);
User getUser(String userId);
boolean updateUser(User user);
boolean deleteUser(User user);
}
E implemente dos versiones: una para pruebas y otra para tiempo de ejecución de producción. La versión para las pruebas se puede implementar 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 marcos ORM
por ejemplo.
Usar el AndroidTestCase:getContext()
solo da un contexto stub en mi experiencia. Para mis pruebas, estoy usando una actividad vacía en mi aplicación principal y obtengo el Context
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é hacen todos los demás?