问题
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.
回答1:
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