[英]How to Unit test the following method
我正在参加软件测试课程,这是我的计算机科学选修课程的一部分。
现在,我们正在测试由研究生制作的软件,它的确不是很漂亮,我正在测试的该类具有以下方法,一开始它似乎使用了线程,并且似乎在创建监听器。听一个端口,有人可以解释一下这段代码在做什么吗? 我将如何测试此功能?
public void startServer() throws IOException {
ServerSocket ss = new ServerSocket(portNum);
while(true) {
Socket s = ss.accept();
Thread t = new Thread(new ConnectionHandler(s));
t.start();
}
}
简而言之:该代码创建了一个新的ServerSocket来侦听特定端口; 当该端口上出现“请求” 时 ,它将启动一个线程来处理该客户端。
该代码的问题:
new
调用。 我将解释如何克服第二部分。 然后谈谈第一点。 关于“测试”本身,您有两种选择:
喜欢:
public class Server {
private final SocketFactory socketFactory;
private final ThreadFactory threadFactory;
public Server() {
this(new SocketFactory(), new ThreadFactory());
}
Server(SocketFactory socketFactory, ...
this.socketFactory = socketFactory...
public void startServer() throws IOException
{
ServerSocket ss = socketFactory.createSocketFor(portNum);
while(true)
{
Socket s = ss.accept();
Thread t = threadFactory.newThreadFor(new ConnectionHandler(s));
t.start();
}
}
现在……一切都变得非常简单:您可以使用第二个受软件包保护的ctor 插入模拟工厂; 然后您可以配置/验证这些工厂是否可以看到您期望的呼叫。
当然,这看起来像是“更多”的工作。 像现在一样,您必须创建其他两个类(实际上,您可能会使用接口加上impl类)。 但问题是:您最终得到了更好的设计,不仅易于测试,而且易于维护和增强。
然后:创建“裸机”线程不再是一种好习惯。 (特别是不是在while-true循环中;如果您仍然在搜索错误),您应该查看一些ThreadPool类。 以确保您不会不断创建新线程。 这些都是“昂贵的”; 您应该非常喜欢“重用”线程。 还有一些库可以帮助您!
好,回到另一个问题:到目前为止,由于while(true),您根本无法合理地对该方法进行单元测试。 您会看到,在模拟该ServerSocket时,对accept()的调用不会阻塞; 并且您遇到了创建模拟线程的无限循环。
所以:你必须改装此代码(以允许外部停止)...或者你可以设置的模拟的ThreadFactory返回一个嘲笑线程; 引发一些特定的异常。 然后,您的单元测试仅希望引发该异常-作为间接“证明”您所期望的事情确实发生了。
该代码的作用是侦听端口。 每次客户端连接时,它将工作委托给一个新线程。 这样,服务器套接字就可用于服务更多请求。
测试连接处理程序可能是可行的,似乎连接处理程序包含最需要测试的代码。 对于其余部分,您将必须创建连接到此套接字的客户端线程,并且此时您编写的内容不是单元测试。 像这样的代码直接实例化类(而不是注入或传递实现接口的对象)使替换模拟变得困难。
我打算编写单元测试以全面介绍连接处理程序,然后创建一个测试工具(可以在另一个jvm中运行的单独程序)以创建连接到该工具的线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.