mockito проверяет вызов метода внутри метода

для модульных тестов я пытаюсь проверить, есть ли способ проверить вызов метода внутри метода с проверкой mockito?

Примером может быть:

public delete(param) {
    VideoService.deleteVideo(param); << i want to verify the call of this method
    return etc.. 
}

Я могу проверить, вызывается ли удаление с помощью:

verify(mock,times(1)).delete(param);

Есть ли способ проверить внутренний метод, например: verify(mock,times(1)).delete(param).VideoService.deleteVideo(param);


person Tvt    schedule 06.04.2016    source источник
comment
Является ли VideoService.deleteVideo статическим методом или VideoService переменной экземпляра?   -  person René Link    schedule 06.04.2016


Ответы (2)


Вы можете использовать шпиона.

public class MyVideoService {

  private VideoService videoService;

  public MyVideoService(VideoService videoService) {
    this.videoService = videoService;
  }

  public void delete(String param) {
    videoService.deleteVideo(param);
  }
}

public class VideoService {
  public void deleteVideo(String param) {
  }
}

Если теперь вы хотите протестировать объект, который использует MyVideoService. Например.

public class ObjectThatUsesMyVideoService {

  private MyVideoService myVideoService;

  ObjectThatUsesMyVideoService(MyVideoService myVideoService) {
    this.myVideoService = myVideoService;
  }

  public void deleteVideo(String param) {
    myVideoService.delete(param);
  }
}

Вы можете написать такой тест

public class MyVideoServiceTest {

  @Test
  public void delete(){
    // VideoService is just a mock
    VideoService videoServiceMock = Mockito.mock(VideoService.class); 

    // Creating the real MyVideoService
    MyVideoService myVideoService = new MyVideoService(videoServiceMock);

    // Creating a spy proxy
    MyVideoService myVideoServiceSpy = Mockito.spy(myVideoService);

    ObjectThatUsesMyVideoService underTest = new ObjectThatUsesMyVideoService(myVideoServiceSpy);

    underTest .deleteVideo("SomeValue");

    // Verify that myVideoService was invoked
    Mockito.verify(myVideoServiceSpy, Mockito.times(1)).delete("SomeValue");

    // Verify that myVideoService invoked the VideoService
    Mockito.verify(videoServiceMock, Mockito.times(1)).deleteVideo("SomeValue");
  }
}
person René Link    schedule 06.04.2016
comment
Но как это работает. Таким образом, я никогда не узнаю, вызывается ли deleteVideo в классе orginall? Не сместит ли это проблему, а не проверит мою реальную ситуацию? - person Tvt; 07.04.2016
comment
Наверное, я просто не знаю, что вы хотите проверить. Пожалуйста, обновите свой вопрос. - person René Link; 07.04.2016
comment
Просто нужно переписать код, он плохо написан, у вашего класса была часть авансера, за это спасибо! :) - person Tvt; 08.04.2016

Предположим, у вас есть класс

class MyVideoService {

 final VideoService videoService;

 public MyVideoService(VideoService videoService) {
   this.videoService = videoService;
 }

 public void delete(param) {
     videoService.deleteVideo(param); 
 }
}

Затем вы издеваетесь над VideoService с помощью

VideoService videoService = mock(VideoService.class);

И создайте MyVideoService с этим издевательским экземпляром, вызовите метод, проверьте:

MyVideService myVideoService = new MyVideoService(videoService);
myVideoService.delete (param);
verify(videoService, times(1)).deleteVideo(param);
person Lukichev    schedule 06.04.2016
comment
Да, это точно так же, как мой первый пример, но это не мой вопрос. Я хочу проверить, вызывается ли videoService.deletevideo(param) при вызове удаления. Есть ли способ для этого? - person Tvt; 06.04.2016
comment
Извините, в моем коде опечатка. Последняя строка должна выглядеть следующим образом: verify(videoService, times(1)).deleteVideo(param); Мы имитируем VideoService, а затем проверяем, вызывался ли его метод при вызове MyVideoService.delete(). - person Lukichev; 06.04.2016
comment
Но что, если вашему конструктору для этого не нужен videoService? и сделать это так, что это существенно сломает его ... Получите awnser, хотя и, вероятно, сработает, если приложение будет разработано по-другому. - person Tvt; 07.04.2016
comment
Немного не ясно, является ли VideoService.deleteVideo(param) вызовом статического метода или videoService является переменной класса. Если это переменная класса, вы должны инициализировать ее либо через конструктор, либо с помощью Spring Autowired инъекции, либо как-то еще. Если это вызов статического метода, может быть достаточно просто проверить, был ли вызван метод переноса delete(), или вы можете подняться на уровень выше с помощью своих тестов и проверить побочный эффект вашего вызова VideoService.deleteVideo(param). Просто проверьте, было ли видео удалено. Это означает, что был вызван рассматриваемый метод. - person Lukichev; 11.04.2016