测试Java套接字 [英] Testing Java Sockets

查看:128
本文介绍了测试Java套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个网络应用程序,我希望得到正确的单元测试。这个时候我们会这样做,你知道吗? :)

I'm developing a network application and I want to get unit testing right. THIS time we'll do it, you know? :)

我在测试网络连接时遇到了麻烦。

I'm have trouble testing network connections, though.

在我的应用程序中,我使用普通的 java.net.Socket s。

In my application I use plain java.net.Sockets.

例如:

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Message {
    byte[] payload;

    public Message(byte[] payload) {
        this.payload = payload;
    }

    public boolean sendTo(String hostname, int port) {
        boolean sent = false;

        try {
            Socket socket = new Socket(hostname, port);

            OutputStream out = socket.getOutputStream();

            out.write(payload);

            socket.close();

            sent = true;
        } catch (UnknownHostException e) {
        } catch (IOException e) {
        }

        return sent;
    }
}

我读过关于嘲笑但不确定如何申请它。

I read about mocking but am not sure how to apply it.

推荐答案

如果我要测试代码,我会执行以下操作。

If I was to test the code, I'd do the following.

首先,重构代码,使 Socket 不会直接在您要测试的方法中实例化。下面的例子显示了我能想到的最小变化。未来的更改可能会将 Socket 创建分解为一个完全独立的类,但我喜欢小步骤,我不喜欢对未经测试的代码进行大的更改。

Firstly, refactor the code so that the Socket isn't directly instantiated in the method you want to test. The example below shows the smallest change I can think of to make that happen. Future changes might factor out the Socket creation to a completely separate class, but I like small steps and I don't like making big changes on untested code.

public boolean sendTo(String hostname, int port) {
    boolean sent = false;

    try {
        Socket socket = createSocket();
        OutputStream out = socket.getOutputStream();
        out.write(payload);
        socket.close();
        sent = true;
    } catch (UnknownHostException e) {
        // TODO
    } catch (IOException e) {
        // TODO
    }

    return sent;
}

protected Socket createSocket() {
    return new Socket();
}

现在套接字创建逻辑超出了您尝试测试的方法,你可以开始模拟并挂钩创建套接字。

Now that the socket creation logic is outside of the method you are trying to test, you can start to mock things up and hook into the creation the socket.

public class MessageTest {
    @Test
    public void testSimplePayload() () {
        byte[] emptyPayload = new byte[1001];

        // Using Mockito
        final Socket socket = mock(Socket.class);
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        when(socket.getOutputStream()).thenReturn(byteArrayOutputStream);

        Message text = new Message(emptyPayload) {
            @Override
            protected Socket createSocket() {
                return socket;
            }
        };

        Assert.assertTrue("Message sent successfully", text.sendTo("localhost", "1234"));
        Assert.assertEquals("whatever you wanted to send".getBytes(), byteArrayOutputStream.toByteArray());
    }
}

覆盖要测试的单位的单个方法确实是对于测试很有用,特别是在具有可怕依赖性的丑陋代码中。显然,最好的解决方案是整理出依赖关系(在这种情况下,我认为消息不依赖于 Socket ,也许有一个 Messager 接口,就像glowcoder建议的那样),但是以最小的步骤向解决方案迈进很不错。

Overriding individual methods on units you want to test is really useful for testing, especially in ugly code with horrible dependencies. Obviously the best solution is sorting out dependencies (in this case I would think that a Message not depend on a Socket, maybe there is a Messager interface as glowcoder suggests), but it's nice to move towards the solution in the smallest possible steps.

这篇关于测试Java套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆