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();
}
Given the above, how can I avoid the calls to JSch
objects. I want to avoid sending of the file to remote server and just want to validate test cases in transfer()
method.
So far I have the following settings:
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());
}
I don't want to exclude the call to put()
or pass throw it to the next statement in the method.
The main problem with using mockito
here is that your connect()
method depends on new JSch()
. Mockito
is not able to mock constructor calls.
But you can change that with a little workaround, as suggested in Michael Feathers book.
Just extract your new JSch()
to the package private getter method
private void connect() throws JSchException {
...
JSch jsch = getJSch();
...
}
JSch getJSch() {
return new JSch();
}
Now in your test, you can override this method to return a mocked instance
private JSch jSch = mock(JSch.class);
private SFTP sftp = new SFTP(){
@Override
JSch getJSch() {
return jSch;
}
};
It's not the most elegant solution but it's the solution worth to consider. Especially if you don't want to do a lot of refactoring.
来源:https://stackoverflow.com/questions/46547763/mocking-sftp-class-skip-method-call