2012-05-10 15 views
4

私は、TCP経由でメッセージを渡すことで、ゲーム同期サーバとの通信を処理するAndroidサービスを提供しています。ネットワーク接続に依存するAndroidサービスの単体テスト方法

このサービスの動作をユニットテストできるようにしたいと考えています。つまり、データが読み込まれ、解析され、有効な対応インテントが送信され、サービスがインテントを受信すると、サーバに送信されるメッセージが正しく作成されます。

私は単体テストについてはあまりよくありませんが、単体テストを私の実践の一部にしようとしています。私はこのようなことにどのようにアプローチするのか分かりません。何とかソケットをモックアップして入出力ストリームを偽造する必要があるように感じますが、特にAndroidに適用されるように、それをどうやって行うのか本当に分かりません。ここで

が(大幅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を使用して、Socketサービスをモックし、Expectationsを使用して、正しいデータがGameSyncServiceなどの上位レベルのメソッドで渡されていることを確認します

1

、私は通常、このような場合には(コンフィギュレーション・クラス上の実際の実装を注入しようとするあなたのソケット、またはあなたが模倣したいもの)か、モッククラスかを指定します。

また、このコンフィグレーションクラスで特定のクラスのインスタンスを多く注入するのに役立つ便利なライブラリが見つかりました。

Socketクラスを注入すると、コンフィグレーションクラスに移動し、定義したコンストラクタをインスタンス化します。これで

@Inject Socket socket; //on your game class

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

あなたはその@SetUpにあなたがこのテストソケット、または別のメッセージモックのモック実装を使用することを定義することができますAndroidのテストプロジェクトを作ることができます1、など

は、それがアイデアを役に立てば幸い:)

関連する問題