2012-11-06 21 views
1

我有一些代码连接到FTP服务器,我正在尝试为该代码编写测试用例。为此,我一直试图使用MockFtpServer来模拟FTP服务器,以便测试我的交互。如何使MockFTPServer抛出异常

http://mockftpserver.sourceforge.net/index.html

在一个特定的情况下,我想测试我的“连接”法,看起来像这样的测试案例:

public class FTPServiceTestWithMock { 

    private FakeFtpServer server; 
    private FTPService service; 
    private int controllerPort; 

    @Before 
    public void setup() { 
     server = new FakeFtpServer(); 
     server.setServerControlPort(0); // Use free port - will look this up later 

     FileSystem fileSystem = new WindowsFakeFileSystem(); 
     fileSystem.add(new DirectoryEntry("C:\\temp")); 
     fileSystem.add(new FileEntry("C:\\temp\\sample.txt", "abc123")); 
     server.setFileSystem(fileSystem); 
     server.addUserAccount(new UserAccount("user", "pass", "C:\\")); 
     server.start(); 
     controllerPort = server.getServerControlPort(); 

     service = new FTPService(); 
    } 

    @After 
    public void teardown() { 
     server.stop(); 
    } 

    @Test 
    public void testConnectToFTPServer() throws Exception { 
     String testDomain = "testdomain.org"; 
     String expectedStatus = 
      "Connected to " + testDomain + " on port " + controllerPort; 

     assertEquals(
      expectedStatus, 
      service.connectToFTPServer(testDomain, controllerPort) 
     ); 
    } 

} 

此代码的工作完美 - 它建立一个假FTP服务器,并将我的代码置于测试中,以确保它可以连接并返回适当的消息。

但是,我的FTP客户端的API规范显示,当我尝试连接时可能会抛出异常。

http://commons.apache.org/net/api-3.1/org/apache/commons/net/SocketClient.html#connect%28java.lang.String%29

我想编写一个异常测试第二次测试的情况下被抛出,这很可能是应该的域名是不正确的或FTP服务器已关闭。我想确保在这种情况下,我的软件能够做出适当的回应。我在模拟FTP服务器网站上找到了关于“自定义命令处理程序”的信息,但我无法弄清楚如何让其抛出异常。这是我有:

public void testConnectToFTPServerConnectionFailed() throws Exception { 
    ConnectCommandHandler connectHandler = new ConnectCommandHandler(); 
    connectHandler.handleCommand(/* Don't know what to put here */); 
    server.setCommandHandler(CommandNames.CONNECT, connectHandler); 
} 

的handleCommand方法需要一个Command对象和Session对象,但我想不通,从文档,如何得到有效的对象发送有谁知道去解决这个问题?

谢谢。

回答

1

由于没有人在这里刺伤,我会给它一个镜头。我以前从未使用过MockFtpServer,所以这是我的第一次尝试。

在我看来,测试服务器是否关闭的最简单方法就是关闭服务器。

@Test(expected = IOException.class) 
public void testConnectToFTPServer_ServerDown() throws Exception { 
    // kill the server 
    server.stop(); 
    service.connectToFTPServer("testdomain.org", controllerPort); 
} 

如果你要测试的是用户名和密码是无效的,也许你可以设置FTP回复代码430: -

@Test(expected = IllegalStateException.class) 
public void testConnectToFTPServer_InvalidUserPassword() throws Exception { 
    // assuming you already started it in setup(), you may want to stop it first 
    if (server.isStarted()) { 
     server.stop(); 
    } 

    ConnectCommandHandler connectCommandHandler = (ConnectCommandHandler) server.getCommandHandler(CommandNames.CONNECT); 

    // 430 = FTP error code for "Invalid username or password" 
    connectCommandHandler.setReplyCode(430); 
    server.setCommandHandler(CommandNames.CONNECT, connectCommandHandler); 
    server.start(); 

    service.connectToFTPServer("testdomain.org", controllerPort); 
} 

我知道你想考SocketException抛出异常由SocketClient.connect() ...这一个有点棘手在这里。基于FTP error codes,我相信你正在拍摄10000系列错误代码之一(如果我在这里错了,请纠正我,但我不是FTP的专家)。这个10000系列错误代码的问题在于,它会让您的测试无限期地旋转,因为错误代码指示远程服务器无法连接,因此在测试MockFtpServer时,测试并不知道何时停止。所以,在这种情况下,我在5秒内将测试设置为超时(我认为这是合理的)。当然,你不会在这里抛出SocketException,但我会认为这个行为足够接近实际的实现代码。

@Test(timeout = 5000) 
public void testConnectToFTPServer_InvalidHostName() throws Exception { 
    // assuming you already started it in setup(), you may want to stop it first 
    if (server.isStarted()) { 
     server.stop(); 
    } 

    ConnectCommandHandler connectCommandHandler = (ConnectCommandHandler) server.getCommandHandler(CommandNames.CONNECT); 

    // 10060 = FTP error code for "Cannot connect to remote server." 
    connectCommandHandler.setReplyCode(10060); 
    server.setCommandHandler(CommandNames.CONNECT, connectCommandHandler); 
    server.start(); 

    service.connectToFTPServer("testdomain.org", controllerPort); 
} 
+0

感谢您的建议,limc。一对夫妇笔记...对于一个,你不需要停止服务器,以取代CommandHandler的功能 - 它只是有助于保持代码更清洁。对于一些事情,比如测试一个错误的密码,只需发送一个错误的密码并获得正确的回复代码就够了。在这方面非常方便的是做一些类似于你的最终测试的东西,在这个测试中,你返回一个10060的回复代码,显示那里有一个套接字,但不接受连接。 – McGlone