public class SFTP {
public Map<Report, TransferStatus> transfer(List<Report> reports) {
//testing logic here
}
private ChannelSftp channelSftp;
private Session session;
private TransferStatus send(File file) {
connect();
send(stream, file.getName());
}
private void send(FileInputStream stream, String name) throws SftpException, IOException {
channelSftp.put(stream, fileNameWithId, new SftpLogMonitor(), ChannelSftp.OVERWRITE);
stream.close();
}
private void connect() throws JSchException {
if (session != null && channelSftp != null) {
return;
}
JSch jsch = new JSch();
jsch.addIdentity(sftpConfig.getSftpPublicKey());
session = jsch.getSession(sftpConfig.getSftpUser(), sftpConfig.getSftpHost(), Integer.parseInt(sftpConfig.getSftpPort()));
session.setUserInfo(new JschUserInfo());
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("sftp");
channelSftp = (ChannelSftp) channel;
channelSftp.connect();
}
给定上述内容,我如何避免对JSch
对象的调用。我想避免将文件发送到远程服务器,而只想在transfer()
方法中验证测试用例。
到目前为止,我有以下设置:
private JSch jSch = mock(JSch.class);
private Session session = mock(Session.class);
private ChannelSftp sftp = mock(ChannelSftp.class);
@Before
public void setUp() throws Exception {
when(jSch.getSession(eq(USERNAME), eq(HOSTNAME), eq(PORT))).thenReturn(session);
when(session.openChannel("sftp")).thenReturn(sftp);
//doNothing().when(sftp).put(Matchers.any());
}
我不想排除对put()
的调用或将其传递给方法中的下一个语句。
使用mockito
的主要问题是您的connect()
方法取决于new JSch()
。Mockito
无法模拟构造函数。但是,正如迈克尔·菲瑟(Michael Feathers)的书中所建议的那样,您可以通过一些解决方法来改变这一点。只需将new JSch()
提取到包装私有Getter方法
private void connect() throws JSchException {
...
JSch jsch = getJSch();
...
}
JSch getJSch() {
return new JSch();
}
现在在测试中,您可以覆盖此方法以返回模拟实例
private JSch jSch = mock(JSch.class);
private SFTP sftp = new SFTP(){
@Override
JSch getJSch() {
return jSch;
}
};
这不是最优雅的解决方案,而是值得考虑的解决方案。特别是如果您不想进行很多重构。
您可以使用下面的命令获取JSCH的模拟实例:
@Mock
JSch jsch;
@Mock
ChannelSftp channelSftp;
@Mock
Session session;
@Before
public void setUp() throws Exception {
Whitebox.setInternalState(SftpConnection.class, "sftpUserName", "test1");
Whitebox.setInternalState(SftpConnection.class, "sftpIpAddress", "test2");
Whitebox.setInternalState(SftpConnection.class, "sftpPort", 0);
Whitebox.setInternalState(SftpConnection.class, "sftpPortPassword", "test3");
PowerMockito.whenNew(JSch.class).withNoArguments().thenReturn(this.jsch);
Mockito.when(this.jsch.getSession("test1", "test2", 0)).thenReturn(this.session);
Mockito.when(this.session.openChannel("sftp")).thenReturn(this.channelSftp);
}