我正在参加软件测试课程,这是我的计算机科学选修课程的一部分。
现在,我们正在测试由研究生制作的软件,它的确不是很漂亮,我正在测试的该类具有以下方法,一开始它似乎使用了线程,并且似乎在创建一个监听器。听一个端口,有人可以解释一下这段代码在做什么吗?我将如何测试此功能?
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返回一个嘲笑线程; 这引发了一些特定的异常。然后,您的单元测试只是希望抛出该异常-作为间接“证明”您所期望的事情确实发生了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句