2012-05-10 4 views
4

나는 TCP를 통해 메시지를주고 받음으로써 게임 동기화 서버와 통신을 처리하는 안드로이드 서비스를 가지고있다.네트워크 연결에 의존하는 안드로이드 서비스를 테스트하는 방법

이 서비스의 동작을 단위 테스트 할 수 있기를 바랍니다. 즉, 데이터가 읽히고 데이터가 읽히고 파싱되어 유효한 해당 인 텐트가 발송되면 서비스가 인 텐트를 수신하면 서버에 보낼 메시지를 올바르게 생성합니다.

나는 단위 테스트에 대해별로 좋지 않지만, 단위 테스트를 내 연습의 일부로 만들고자합니다. 이런 식으로 접근하는 방법을 잘 모르겠습니다. 그것은 마치 소켓을 조롱하고 입력 및 출력 스트림을 가짜로 만들 필요가 있다고 생각하지만, 안드로이드에 적용 할 때 그렇게하는 법을 정말로 모릅니다. 여기

가 (크게 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

조롱의 세계에 오신 것을 환영합니다. 당신이해야 할 일은 Android Mock의 도움으로 쉽게 할 수 있습니다. 프로젝트의 Writing Tests using Android Mock wiki 페이지에서 Expectations가 Android Mock에서 작동하는 방식을 읽어야합니다.

내가 할 것은 기본 TCP/소켓 호출을 캡슐화하는 소켓 서비스를 구현하는 것입니다. 그런 다음 Android Mock을 사용하여 소켓 서비스를 조롱하고 Expectations를 사용하여 올바른 데이터가 GameSyncService와 같은 상위 수준 메소드에 전달되었는지 확인

1

, 나는 보통이 경우에는 (구성 클래스의 실제 구현을 주입하려고 당신의 소켓 또는 모의하고 싶은 것) 또는 모의 수업.

이 구성 클래스에서 특정 클래스의 인스턴스를 많이 주입하는 데 도움이되는 Roboguice 라이브러리가 유용하다는 사실도 알게되었습니다.

Socket 클래스를 삽입하면 구성 클래스로 이동하고 정의한 생성자를 인스턴스화합니다. 당신이 @SetUp에서 할 수있는 안드로이드 테스트 프로젝트를 만들 수있는이와

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

@Inject Socket socket; //on your game class

는이 테스트에서 소켓 또는 다른에서 메시지 모의에 대한 모의 구현을 사용하는 것으로 정의 하나 등

희망과 함께 도움 :

관련 문제