実際、私の質問は2つの部分に分かれています。FTPサーバーからファイルを取得するクラスを適切に単体テストする方法
- 私のテストを外部から隔離しても、その機能が動作することを確認するにはどうすればよいですか?
- Mockitoを使用してFtpClientクラスを共有するにはどうすればよいですか?私はそれを嘲笑するとき、私は、nullを取得:
InputStream InputStreamは= ftpClient.retrieveFileStream(ftpParameters.getSourceFileName());
はここでのテストクラスです:
public class SimpleFtpFileImporterTest {
FtpParameters ftpParams =new FtpParameters();
SimpleFtpFileImporter fileImporter=new SimpleFtpFileImporter();
FTPClient ftpMock= mock(FTPClient.class);
@Before
public void startup(){
this.ftpParams.setServer("10.0.206.126");
this.ftpParams.setPort(21);
this.ftpParams.setUserName("mikola");
this.ftpParams.setPassword("password");
this.ftpParams.setSourceFileName("readme.txt");
}
@Test
public void returnNullWhenFileCouldNotBeFetchedCompletely() throws IOException{
when(ftpMock.completePendingCommand()).thenReturn(false);
fileImporter=new SimpleFtpFileImporter(ftpMock);
byte[] bytes= fileImporter.downloadFile(ftpParams);
assertNull(bytes);
}
}
そしてここでは、テスト対象のシステムです:
public class SimpleFtpFileImporter implements IFileImporter {
private FTPClient ftpClient;
static Logger logger = Logger.getLogger(SimpleFtpFileImporter.class);
static {
PropertyConfigurator.configure("config/log4j.properties");
}
/**
* Creates a SimpleFtpFileImporter class instance passing an FtpClient.
* This constructor helps create unit tests by passing any kind of FTPClient, eg. an http ftp client.
*
* @param ftpClient An FTPClient object
*/
public SimpleFtpFileImporter(FTPClient ftpClient) {
this.ftpClient = ftpClient;
}
public SimpleFtpFileImporter() {
}
/**
* Gets the file specified from the specified FTP server
*
* @param ftpParameters An FtpParametrs object that bears the needed information
* @return File in byte array if successful, otherwise null
*/
public byte[] downloadFile(FtpParameters ftpParameters) {
if (this.ftpClient == null)
this.ftpClient = new FTPClient();
if (!ftpParameters.isProperlyPopulated()) {
logger.warn("Not all FTP parameters have been set. Execution will halt.");
throw new FtpParametersNotSetException("Ftp parameters not properly set.");
}
try {
ftpClient.connect(ftpParameters.getServer());
ftpClient.login(ftpParameters.getUserName(), ftpParameters.getPassword());
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
logger.info("FTP connection succesfully established. Preparing to retrieve file:"+ftpParameters.getSourceFileName());
InputStream inputStream = ftpClient.retrieveFileStream(ftpParameters.getSourceFileName());
if (inputStream != null) {
byte[] bytes = IOUtils.toByteArray(inputStream);
boolean success = ftpClient.completePendingCommand();
logger.info("File received");
inputStream.close();
if (success) {
return bytes;
} else{
logger.warn("File fetching process could not be through. Returning null.");
return null;
}
}else{
logger.warn("Wrong file name specified. File name:"+ftpParameters.getSourceFileName());
throw new RuntimeException("Wrong file name specified");
}
} catch (IOException ex) {
logger.error("Problem while trying to get file from remote FTP. Message: " + ex.getMessage() + " \n\r" + ex);
}
return null;
}
}
嘲笑FtpClientオブジェクトは本物を作るのに適していないようで、必要なすべてのパラメータ(ホスト、ポート、ユーザー名とパスワード)を提供しますが、
私はちょっと驚いています。この質問は初心者から「なぜ私のコードがうまくいかないのか」と尋ねたようなものです。真剣に:[mcve]を提供してください。あなたが求めているのは、土地を嘲笑いながら "日常のビジネス"です。だから確かにあなたのコードにいくつかの単純なバグがあります;-) – GhostCat
Nnnnnn [OK]を、私はいくつかのコードを追加します –
私の答えは私の更新をしてください。 – GhostCat