模拟Sftp类跳过方法调用

时间:2017-10-03 15:05:20

标签: java junit mocking mockito jsch

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()的调用或将其传递给方法中的下一个语句。

2 个答案:

答案 0 :(得分:0)

此处使用mockito的主要问题是,connect()方法取决于new JSch()Mockito无法模拟构造函数调用。 但是您可以通过Michael Feathers book中的建议稍微改变一下。 只需将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;
    }
};

这不是最优雅的解决方案,但它是值得考虑的解决方案。特别是如果你不想做很多重构。

答案 1 :(得分:-3)

您可以使用以下命令来获取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);
}