9

for a unit tests i am trying to verify if there is a way to verify a method call inside a method with mockito verify?

An example would be:

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

I can check if delete is called with :

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

Is there also like a way to check the inside method like: verify(mock,times(1)).delete(param).VideoService.deleteVideo(param);

Tvt
  • 223
  • 1
  • 3
  • 16

2 Answers2

4

You can use a spy.

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) {
  }
}

If you now want to test an object that uses MyVideoService. E.g.

public class ObjectThatUsesMyVideoService {

  private MyVideoService myVideoService;

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

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

You can write a test like this

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");
  }
}
René Link
  • 48,224
  • 13
  • 108
  • 140
  • But how does this work. This way i will never know if the deleteVideo is called in the orginall class? Won't this just move the problem and not test my real-situation? – Tvt Apr 07 '16 at 08:12
  • I guess I just don't know what you want to test. Please update your question. – René Link Apr 07 '16 at 14:55
  • Just need to rewrite the code it's poorly written your class had part of the awnser for this to thank you! :) – Tvt Apr 08 '16 at 07:45
1

Lets assume you have a class

class MyVideoService {

 final VideoService videoService;

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

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

Then you mock VideoService with

VideoService videoService = mock(VideoService.class);

And create MyVideoService with this mocked instance, call method, verify:

MyVideService myVideoService = new MyVideoService(videoService);
myVideoService.delete (param);
verify(videoService, times(1)).deleteVideo(param);
Lukichev
  • 11
  • 3
  • Yea this is exacly like mi first example but this is not my question.. I want to verify if videoService.deletevideo(param) is called when delete is called is there a way for this? – Tvt Apr 06 '16 at 13:54
  • Sorry, there is a typo in my code. The last line should read like this: verify(videoService, times(1)).deleteVideo(param); We mock VideoService and then verify whether its method been called when the MyVideoService.delete() is called. – Lukichev Apr 06 '16 at 14:02
  • But what if your constructor doesnt need videoService to do this? and making it so woud bassicly break it ... Get the awnser though and would probarly work if the application was designed another way. – Tvt Apr 07 '16 at 08:32
  • It is a bit not clear whether `VideoService.deleteVideo(param)` is a static method call or `videoService` is a class variable. If it is a class variable, you should initialise it either via constructor or by spring autowired injection or somehow else. If it is a static method call it may be enough just to test whether wrapping `delete()` method has been called or you may move a level higher with your tests and test for the side effect of your `VideoService.deleteVideo(param)` call. Just test whether video has been deleted. It means that the method under consideration has been called. – Lukichev Apr 11 '16 at 08:22