Zor*_*ric 30 java sockets unit-testing mocking
我正在开发一个网络应用程序,我希望得到正确的单元测试.这个时候我们会这样做,你知道吗?:)
不过,我在测试网络连接时遇到了麻烦.
在我的应用程序中,我使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
我读到了关于嘲笑但不确定如何应用它.
Jef*_*ter 55
如果我要测试代码,我会做以下事情.
首先,重构代码,以便Socket不在要测试的方法中直接实例化.下面的例子显示了我能想到的最小变化.未来的更改可能会将Socket创建分解为一个完全独立的类,但我喜欢小步骤,我不喜欢对未经测试的代码进行重大更改.
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();
}
Run Code Online (Sandbox Code Playgroud)
现在套接字创建逻辑不在您尝试测试的方法之外,您可以开始模拟并挂钩创建套接字.
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());
}
}
Run Code Online (Sandbox Code Playgroud)
在要测试的单元上覆盖单个方法对于测试非常有用,尤其是在具有可怕依赖性的丑陋代码中.显然,最好的解决方案是整理出依赖关系(在这种情况下,我认为Message不依赖于a Socket,也许有一个Messager接口就像glowcoder建议的那样),但是以最小的步骤向解决方案迈进是很好的.
Bil*_*l K 11
我将按照要求回答您的问题,而不是重新设计您的课程(其他人已经涵盖了这些问题,但是关于课程的基本问题仍然有效).
单元测试从不测试被测试类之外的任何东西.这会让我的大脑受到一段时间的伤害 - 这意味着单元测试不会以任何方式证明你的代码有效!它的作用是证明您的代码与编写测试时的代码相同.
所以说你想要这个类的单元测试,但你也想要一个功能测试.
对于单元测试,您必须能够"模拟"通信.要做到这一点而不是创建自己的套接字,从"套接字工厂"中获取一个,然后自己做一个套接字工厂.应该将工厂传递给您正在测试的此类的构造函数.这实际上并不是一个糟糕的设计策略 - 您可以在工厂中设置主机名和端口,这样您就不必在通信类中了解它们 - 更抽象.
现在在测试中你只是传入一个模拟工厂,创建模拟套接字,一切都是玫瑰.
不要忘记功能测试!设置一个可以连接的"测试服务器",将一些消息发送到服务器并测试您收到的响应.
就此而言,您可能希望进行更深入的功能测试,其中您编写一个客户端,向REAL服务器发送一些脚本命令并测试结果.您甚至可能只想为功能测试创建"重置状态"命令.功能测试实际上确保整个"功能单元"按预期一起工作 - 这是许多单元测试倡导者忘记的事情.
| 归档时间: |
|
| 查看次数: |
53194 次 |
| 最近记录: |