我有一个类FTPOperation,我用它作为基类重新组合FTP操作常用的方法。其中一种方法是connect()。
public abstract class FtpOperation {
protected static final Log log = LogFactory.getLog(FtpOperation.class);
/**
* Hostname or IP address of the FTP server (e.g. localhost, 127.0.0.1).
*/
private String hostName;
private String username;
private String password;
protected FTPClient ftpClient = getFTPClient();
public void setHostName(String hostName) {
this.hostName = hostName;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
/**
* Connect to the specified FTP server.
*
* @throws Exception
*/
protected void connect() throws Exception {
int reply;
// Connect to the FTP server
ftpClient.connect(hostName);
if (!ftpClient.login(username, password))
throw new Exception("Fail to log in with the given credentials.");
log.info("Connected to " + hostName + ".");
log.info(ftpClient.getReplyString());
// Check if the connection succeeded
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
throw new Exception("Connection to FTP server failed with code "
+ reply + ".");
}
/**
* Used for mocking.
*
* @return
*/
protected FTPClient getFTPClient() {
if (this.ftpClient == null)
this.ftpClient = new FTPClient();
return ftpClient;
}
}
我想编写测试此方法的单元测试,但我不知道如何测试它。我使用Mockito为FTPClient实例创建一个模拟对象。 首先,我考虑测试ftpClient.connect()调用返回某个异常的不同情况,但我认为这是错误的,因为我通过知道connect()方法的实现而不是通过API进行测试。 我已经完成了测试的例子:
@Test(expected = SocketException.class)
public void testConnectSocketException() throws Exception {
downloadInitialFileTasklet.setHostName("hostname");
doThrow(new SocketException()).when(mockFtpClient).connect("hostname");
downloadInitialFileTasklet.connect();
}
有人可以解释一下测试这种方法的正确方法吗?
由于
答案 0 :(得分:1)
为FtpClient类创建一个接口,而不是将其包装到您将在生产环境中使用的新类中。
对于测试而言,您可以实现存根(假类)或包装的FtpClient的模拟对象(我更喜欢第一种方式)。
将IFtpClient接口传递给FtpOperation类的构造函数。
答案 1 :(得分:1)
您的测试意味着要测试什么?如果您只是看到SocketException没有被捕获,那么它似乎是一个特殊的测试。
如果要包装异常,那么它会更有意义。 例如
protected void connect() throws FTPException {
int reply;
// Connect to the FTP server
try {
ftpClient.connect(hostName);
} catch (IOException e) {
throw new FTPException(e, "unable to connect to: "+hostname);
}
...
}
通过测试,我们测试连接是否正确终止,如果底层客户端无法连接则抛出FTPException
@Test(expected = FTPException.class)
public void ConnectFailsIfExceptionOnClientConnect() throws FTPException {
// setup
downloadInitialFileTasklet.setHostName("hostname");
when(mockFtpClient).connect(any(String.class)).doThrow(new SocketException());
// verify -- if something else throws an FTP exception later then the verify
// statements should fail the test because either connect was not called
// because or login was
verify(mockFtpClient).connect(any(String.class));
verify(mockFtpClient, never()).login(any(String.class), any(String.class));
downloadInitialFileTasklet.connect();
}