Jsch имитирует Java — Mockito/ PowerMockito

Я пытаюсь написать модульный тест для следующего фрагмента кода и испытываю трудности. Пожалуйста помоги. Я не знаю, как писать тесты, особенно для методов, возвращающих void, таких как addIdentity() и connect(). Я использую Mockito и фреймворк powerMockito.

public class A {

public method1() {
//some code here
method2();
//more code here
} 

private void method2() {
JSch jsch = new JSch();
Session jschSession = null;
    try {
        jsch.addIdentity("key");
        jschSession = jsch.getSession("userID", "somedomain", 22);
        //jsch code
        }
    }    
}

и вот как выглядят мои тесты:

@Test
public void my_Test() throws JSchException {    
    A test = new A();
    JSch mockJsch = Mockito.mock(JSch.class);
    whenNew(JSch.class).withNoArguments().thenReturn(mockJsch);
    test.method1();
}

person stdio.h    schedule 16.12.2020    source источник
comment
Модульный тест для этого фрагмента кода должен имитировать JSch и проверять, что он вызывается так, как вы ожидаете, в различных условиях.   -  person tgdavies    schedule 16.12.2020
comment
Я написал этот код, но он не работает при вызове метода addIdentity mockJsch = Mockito.mock(JSch.class); whenNew(JSch.class).withNoArguments().thenReturn(mockJsch);   -  person stdio.h    schedule 16.12.2020
comment
Добавьте свой код к своему вопросу, а также точное сообщение об ошибке/трассировку стека.   -  person tgdavies    schedule 16.12.2020


Ответы (1)


Имитация JSch не поможет вам с текущей реализацией, потому что вы всегда используете создание нового экземпляра JSch с new. Таким образом, у вас в настоящее время нет возможности передать извне издевательскую версию JSch.

Лучшим подходом было бы передать экземпляр JSch как часть конструктора A. Это дает вам возможность передавать любой экземпляр JSch во время тестирования. Затем во время выполнения вы можете использовать инфраструктуру внедрения зависимостей (например, Spring или CDI, которая является частью Jakarta EE/Microprofile/Quarkus), чтобы ввести экземпляр (после того, как вы его объявили).

Вы можете реорганизовать свой класс A следующим образом:

public class A {

  private final JSch jsch;

  public A (Jsch jsch) {
    this.jsch = jsch;
  }

  public method1() {
    //some code here
    method2();
    //more code here
 } 

  private void method2() {
    com.jcraft.jsch.Session jschSession = null;
    try {
        jsch.addIdentity("key");
        jschSession = jsch.getSession("userID", "somedomain", 22);
        jschSession.setConfig("StrictHostKeyChecking", "no");
        jschSession.connect();
        Channel channel = jschSession.openChannel("sftp");
        channel.connect();
        ChannelSftp sftpObj = (ChannelSftp) channel;
        sftpObj.exit();
        jschSession.disconnect();
      }
   }    
}

И затем вы можете передать издевательский экземпляр Jsch в тестируемый класс (A) и получить полный контроль над поведением Jsch

@Test
public void my_Test() throws JSchException {   
    JSch mockJsch = Mockito.mock(JSch.class); 
    A test = new A(mockJsch);
    when(mockJsch.getSession("", "").thenReturn(yourSession);
    test.method1();
}

Для этого теста нет необходимости использовать PowerMock, и я бы предпочел просто использовать JUnit и Mockito.

person rieckpil    schedule 16.12.2020