如何对依赖于网络连接的Android服务进行单元测试

如何对依赖于网络连接的Android服务进行单元测试,android,unit-testing,sockets,service,Android,Unit Testing,Sockets,Service,我有一个Android服务,通过TCP来回传递消息来处理与游戏同步服务器的通信 我希望能够对该服务的行为进行单元测试。也就是说,当在线路上看到数据时,数据被读取、解析并发出有效的对应意图,当服务接收到意图时,它会正确地创建一条要发送到服务器的消息 我对单元测试不是特别在行,但我正试图让单元测试成为我实践的一部分。我不知道如何处理这样的事情。感觉好像我需要模拟套接字并伪造输入和输出流,但我真的不知道该怎么做,尤其是在Android上 以下是(为breverity大幅缩减)服务: 我在自己的项目中确

我有一个Android服务,通过TCP来回传递消息来处理与游戏同步服务器的通信

我希望能够对该服务的行为进行单元测试。也就是说,当在线路上看到数据时,数据被读取、解析并发出有效的对应意图,当服务接收到意图时,它会正确地创建一条要发送到服务器的消息

我对单元测试不是特别在行,但我正试图让单元测试成为我实践的一部分。我不知道如何处理这样的事情。感觉好像我需要模拟套接字并伪造输入和输出流,但我真的不知道该怎么做,尤其是在Android上

以下是(为breverity大幅缩减)服务:


我在自己的项目中确实发现了这个问题,我通常尝试在配置类中注入真正的实现(在本例中是套接字或您想要模拟的内容)或模拟类

我还发现这个库非常有用,它可以帮助在这个配置类上注入某些类的实例

注入套接字类将转到配置类并实例化所定义的构造函数

@injectsocket//在游戏课上

bind(Socket.class).toInstance(socketimplementation)//在应用程序类上

有了它,您可以创建一个Android测试项目,它可以在@SetUp中定义您将在这个测试中使用套接字的模拟实现,或者在另一个测试中使用消息mock,等等


希望它能帮上忙:)

欢迎来到嘲笑的世界。你需要做的事可以在你的帮助下轻松完成。您应该在项目的wiki页面上阅读期望如何与Android Mock一起工作

我要做的是实现一个封装底层TCP/Socket调用的套接字服务。然后使用Android Mock模拟套接字服务,并使用期望值验证更高级别的方法(如GameSyncService)传入的数据是否正确

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();
    }
}