Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify static void method has been called with power mockito

I am using the following.

Powermock-mockito 1.5.12 Mockito 1.95 junit 4.11 

Here is my utils class

public void InternalUtils {     public static void sendEmail(String from, String[] to, String msg, String body) {     } } 

here is gist of the class under test:

public class InternalService {        public void processOrder(Order order) {            if (order.isSuccessful()) {                InternalUtils.sendEmail(...);            }        } } 

And here is the test:

@PrepareForTest({InternalUtils.class}) @RunWith(PowerMockRunner.class) public class InternalService {    public void verifyEmailSend() {         mockStatic(Internalutils.class);         doNothing().when(InternalUtils, "sendEmail", anyString(), any(String.class), anyString(), anyString());         Order order = mock(Order.class);         when(order.isSuccessful()).thenReturn(true);         InternalService is = new InternalService();          verifyStatic(times(1));         is.processOrder(order);    } } 

The above test fails. The verification mode given is none, but according to the code, if order is successful than email must be send.

like image 649
Chun ping Wang Avatar asked Aug 27 '13 13:08

Chun ping Wang


People also ask

How do I verify a void in Mockito?

Using the verify() Method Mockito provides us with a verify() method that lets us verify whether the mock void method is being called or not. It lets us check the number of methods invocations. So, if the method invocation returns to be zero, we would know that our mock method is not being called.

Does Mockito verify call the method?

Mockito Verify methods are used to check that certain behavior happened. We can use Mockito verify methods at the end of the testing method code to make sure that specified methods are called.

How verify method works in Mockito?

Mockito. verify() will just verify that an invocation was done on a mock during the method execution. It means that if the real implementation of the mocked class doesn't work as it should, the test is helpless. As a consequence, a class/method that you mock in a test have also to be unitary tested.


2 Answers

If you are mocking the behavior (with something like doNothing()) there should really be no need to call to verify*(). That said, here's my stab at re-writing your test method:

@PrepareForTest({InternalUtils.class}) @RunWith(PowerMockRunner.class) public class InternalServiceTest { //Note the renaming of the test class.    public void testProcessOrder() {         //Variables         InternalService is = new InternalService();         Order order = mock(Order.class);          //Mock Behavior         when(order.isSuccessful()).thenReturn(true);         mockStatic(Internalutils.class);         doNothing().when(InternalUtils.class); //This is the preferred way                                                //to mock static void methods.         InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());          //Execute         is.processOrder(order);                      //Verify         verifyStatic(InternalUtils.class); //Similar to how you mock static methods                                            //this is how you verify them.         InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString());    } } 

I grouped into four sections to better highlight what is going on:

1. Variables

I choose to declare any instance variables / method arguments / mock collaborators here. If it is something used in multiple tests, consider making it an instance variable of the test class.

2. Mock Behavior

This is where you define the behavior of all of your mocks. You're setting up return values and expectations here, prior to executing the code under test. Generally speaking, if you set the mock behavior here you wouldn't need to verify the behavior later.

3. Execute

Nothing fancy here; this just kicks off the code being tested. I like to give it its own section to call attention to it.

4. Verify

This is when you call any method starting with verify or assert. After the test is over, you check that the things you wanted to have happen actually did happen. That is the biggest mistake I see with your test method; you attempted to verify the method call before it was ever given a chance to run. Second to that is you never specified which static method you wanted to verify.

Additional Notes

This is mostly personal preference on my part. There is a certain order you need to do things in but within each grouping there is a little wiggle room. This helps me quickly separate out what is happening where.

I also highly recommend going through the examples at the following sites as they are very robust and can help with the majority of the cases you'll need:

  • https://github.com/powermock/powermock/wiki/Mockito (PowerMock Overview / Examples)
  • http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html (Mockito Overview / Examples)
like image 106
Matt Lachman Avatar answered Sep 29 '22 03:09

Matt Lachman


Thou the above answer is widely accepted and well documented, I found some of the reason to post my answer here :-

    doNothing().when(InternalUtils.class); //This is the preferred way                                            //to mock static void methods.     InternalUtils.sendEmail(anyString(), anyString(), anyString(), anyString()); 

Here, I dont understand why we are calling InternalUtils.sendEmail ourself. I will explain in my code why we don't need to do that.

mockStatic(Internalutils.class); 

So, we have mocked the class which is fine. Now, lets have a look how we need to verify the sendEmail(/..../) method.

@PrepareForTest({InternalService.InternalUtils.class}) @RunWith(PowerMockRunner.class) public class InternalServiceTest {      @Mock     private InternalService.Order order;      private InternalService internalService;      @Before     public void setup() {         MockitoAnnotations.initMocks(this);         internalService = new InternalService();     }      @Test     public void processOrder() throws Exception {          Mockito.when(order.isSuccessful()).thenReturn(true);         PowerMockito.mockStatic(InternalService.InternalUtils.class);          internalService.processOrder(order);          PowerMockito.verifyStatic(times(1));         InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString());     }  } 

These two lines is where the magic is, First line tells the PowerMockito framework that it needs to verify the class it statically mocked. But which method it need to verify ?? Second line tells which method it needs to verify.

PowerMockito.verifyStatic(times(1)); InternalService.InternalUtils.sendEmail(anyString(), any(String[].class), anyString(), anyString()); 

This is code of my class, sendEmail api twice.

public class InternalService {      public void processOrder(Order order) {         if (order.isSuccessful()) {             InternalUtils.sendEmail("", new String[1], "", "");             InternalUtils.sendEmail("", new String[1], "", "");         }     }      public static class InternalUtils{          public static void sendEmail(String from, String[]  to, String msg, String body){          }      }      public class Order{          public boolean isSuccessful(){             return true;         }      }  } 

As it is calling twice you just need to change the verify(times(2))... that's all.

like image 43
Arpit Avatar answered Sep 29 '22 03:09

Arpit