Cómo ensayar un servicio de Android que depende de una conexión de red

Tengo un servicio de Android que maneja las comunicaciones con un servidor de sincronización de juegos al pasar mensajes sobre TCP de un lado a otro.

Me gustaría poder probar en unidad el comportamiento de este servicio. Es decir, cuando se ve en el cable que los datos se leen, analizan y envían la intención correspondiente válida y cuando el Servicio recibe una Intención, crea correctamente un mensaje que se enviará al servidor.

No soy particularmente bueno sobre las pruebas de unidad, pero estoy tratando de hacer parte de las pruebas de unidad de mi práctica. No estoy seguro de cómo abordar algo como esto. Se siente como de alguna manera que tendría que simular socket y falsificar los flujos de entrada y salida, pero realmente no sé cómo hacer que, especialmente cuando se aplica a Android.

Aquí está el servicio (muy recortado para breverity):

public class GameSyncService extends Service { Thread mInputThread = new Thread() { /** * Parse commands from a message string, broadcast the command intents, and * return the remainder of the message * @param message The message to parse for commands * @returns the remaining characters */ private String parseCommands(String message) { // Parse the command, Broadcast the Intent and return any remainder } @Override public void run() { String message = ""; int charsRead = 0; char [] buffer = new char[BUFFER_SIZE]; while(!Thread.interrupted()) { try { while ((charsRead = mIn.read(buffer)) != -1) { message += new String(buffer).substring(0, charsRead); message = parseCommands(message); } } catch (IOException e) { Log.d(LOG_TAG, "Error receiving response: " + e.getLocalizedMessage()); disconnectFromServer(); connectToServer(); } } } }; private BroadcastReceiver mMessageSender = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String message = intent.getStringExtra("message"); sendMessage(message); } }; @Override public IBinder onBind(Intent arg0) { return null; } private void sendMessage(String message) { new SendCommandMessageTask().execute(message); } /** * Create a new connection to the server */ private void connectToServer() { try { if (mSocket == null) { mSocket = new Socket(mHost, mPort); mOut = new PrintWriter(mSocket.getOutputStream()); mIn = new BufferedReader(new InputStreamReader(mSocket.getInputStream()), BUFFER_SIZE); sendMessage("Handshake:|" + pInfo.versionName); } } catch (IOException e) { e.printStackTrace(); } } /** * Disconnect from the server and reset the socket to null */ private void disconnectFromServer() { if (mSocket != null) { try { mIn.close(); mOut.close(); mSocket.close(); mSocket = null; } catch (IOException e) { e.printStackTrace(); } } } @Override public int onStartCommand(Intent i, int flags, int startId) { Log.d(LOG_TAG, "GameSyncService Started"); mHost = i.getStringExtra("host"); mPort = i.getIntExtra("port", 9000); connectToServer(); mInputThread.start(); return START_STICKY; } @Override public void onCreate() { registerReceiver(mMessageSender, new IntentFilter(COMMAND_MESSAGE_SEND_ACTION)); try { pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); } catch (NameNotFoundException e) { e.printStackTrace(); } super.onCreate(); } @Override public void onDestroy() { unregisterReceiver(mMessageSender); super.onDestroy(); } } 

2 Solutions collect form web for “Cómo ensayar un servicio de Android que depende de una conexión de red”

Bienvenido al mundo de la burla. Lo que necesitas hacer se puede hacer fácilmente con la ayuda de Android Mock . Usted debe leer sobre cómo funcionan las expectativas con Android Mock en las pruebas de escritura del proyecto usando la página wiki de Android Mock .

Lo que haría es implementar un servicio Socket que encapsula las llamadas TCP / socket subyacentes. Luego, usando Android Mock, se burla de su servicio Socket y utiliza Expectations para verificar que los datos correctos son pasados ​​por un método de nivel superior (como GameSyncService)

Encontré este problema en mi propio proyecto, por lo general intento inyectar en una clase de configuración la implementación real (en este caso su Socket o lo que quiere simular) o la clase simulado.

También encontré realmente útil la biblioteca de Roboguice que ayuda mucho inyectar instancias de una cierta clase en esta clase de configuración.

Inyectar su clase Socket irá a su clase de configuración e instanciará el constructor que ha definido.

@Inject Socket socket; //on your game class

bind(Socket.class).toInstance(socketImplentation); //on your Application class

Con esto usted puede hacer un proyecto de prueba de Android que puede en su @SetUp definir que va a utilizar la aplicación simulada para el socket en esta prueba, o el mensaje de simulación en otro, etc

Espero que ayude con la idea 🙂

  • Genymotion se comunica con socket en diferentes subredes locales
  • Socket timeout usando android marshmallow. Android <6 funciona. ¿Ha cambiado algo?
  • Android illegalxception
  • Patrón o mejor práctica para una aplicación cliente de socket simple
  • Problema con la conexión Bluetooth de Android
  • ¿Cómo mostrar la imagen JPEG directamente desde la matriz de bytes (antes de guardar la imagen)?
  • Error de Java en el servidor WebSocket
  • ¿Cómo se puede forzar una descarga en un objeto OutputStream sin cerrarlo?
  • Recuperar mediante programación los datos de uso de la red de etiquetas en Android
  • Tcp conexión otro dispositivo android, basado en # teléfono en lugar de IP?
  • Uso incorrecto de BufferedReader
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.