John A Qualls
John A Qualls

Reputation: 849

PowerMockito.verifyStatic() Problems

I need to use PowerMockito to test if a specific static method is called. I am using the following PowerMockito and JUnit libraries ...

I am having issues getting the PowerMockito.verifyStatic() method to work properly. In the following code example, I have tried using the @PrepareForTest, and mockStatic(), and I have tried excluding them. In the code example I include them.

Test Class:

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Test1.class)
public class PowerMockTest {
    @Test
    public void staticVerifyTest() {
        PowerMockito.mockStatic(Test1.class);

        // Test
        PowerMockito.verifyStatic();
        //Test1.staticMethod();
    }
}

Class Under Test:

public class Test1 {
    public static void staticMethod() {
        System.out.println("Static Method!");
    }
}

The test passes when it is run, but it should fail because Test1.staticMethod() is never called. Any help on this would be greatly appreciated!

Upvotes: 15

Views: 51415

Answers (4)

user944849
user944849

Reputation: 14971

Using powermock-api-mockito2 and powermock-module-junit4 version 2.0.7 and either Mockito 2.28.2 or 3.3.3, with a test defined like the below, I kept getting an error about "TooManyActualInvocations: Wanted 1 time but was 2 times."

public class StaticClass {
  // Note: void method with arguments
  public static void doSomething(final String arg) {
    doSomethingElseWithArg(arg);
  }
}

public class ClassUnderTest {
  public void doWork(String arg) {
    StaticClass.doSomething(arg);
  } 
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticClass.class)
public class MyTest {
  ClassUnderTest tester = new ClassUnderTest();

  @Test 
  public void myStaticTest() throws Exception {
    PowerMockito.mockStatic(StaticClass.class);
    StaticClass.doSomething("hello");  // won't work

    tester.doWork("hello");

    PowerMockito.verifyStatic(StaticClass.class);
    StaticClass.doSomething("hello"); // TooManyActualInvocations 
  }
}

After doublechecking that the original code was not calling the method twice, much doc reading and many bunny trails, I finally got it to work. The test method needed to look like this instead:

@Test 
public void myStaticTest() throws Exception {
  PowerMockito.mockStatic(StaticClass.class);
  PowerMockito.doNothing().when(StaticClass.class, "doSomething", "hello"); 

  tester.doWork("hello");

  PowerMockito.verifyStatic(StaticClass.class);
  // specify the method and the args expected in the call
  StaticClass.doSomething("hello");
}

It took me so long to figure this out I'm documenting for the next person.

Upvotes: 1

Fabio
Fabio

Reputation: 101

It's not an answer in itself but A) a confirmation that Oliver's comment about the method change is still valid at PowerMock 2.0.2 and B) a note with additional information on how it works.

PowerMockito.verifyStatic() calls Mockito.verify() which has a few examples at its Javadoc:

verify(mock, times(5)).someMethod("was called five times");
verify(mock, atLeast(2)).someMethod("was called at least two times");

As this sintax is not available anymore we need 2 lines of code to declare the validation rule. Using John's example this means that the first 3 lines would be "actual" business calls and the one after verifyStatic is just telling it which call counter must match the 2nd parameter:

PowerMockito.mockStatic(Test1.class);

// Test
Test1.staticMethod();
Test1.staticMethod();
Test1.staticMethod();

// Validation
PowerMockito.verifyStatic(Test1.class, Mockito.times(3));
Test1.staticMethod();

Upvotes: 10

Oliver Collins
Oliver Collins

Reputation: 116

For me, I encountered this issue when upgrading to powermock 2.0.0-beta.5 from 1.7.0 and so these solutions posted above DID NOT help solve my problem. Instead, I had to add the mocked class inside of the verify static call as posted within the documentation for powermock (https://static.javadoc.io/org.powermock/powermock-api-mockito/1.7.1/deprecated-list.html)

So I went from:

PowerMockito.verifyStatic(Mockito.times(1));

to:

PowerMockito.verifyStatic(Test1.class, Mockito.times(1));

This solved my problem when using the libraries below:

testCompile group: 'org.mockito', name: 'mockito-core', version: '2.18.0'
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0-beta.5'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0-beta.5'

Upvotes: 8

John A Qualls
John A Qualls

Reputation: 849

Alright, I figured it out thanks to Stefan Birkner's reference

Here is the correction to my sample code:

import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Test1.class)
public class PowerMockTest {
    @Test
    public void staticVerifyTest() {
        PowerMockito.mockStatic(Test1.class);
        // Test
        Test1.staticMethod();
        PowerMockito.verifyStatic();
        Test1.staticMethod();
    }
}

After the static method is invoked, you need to verify that it was called by calling it again after your verifyStatic() call.

i.e.

        Test1.staticMethod();
        PowerMockito.verifyStatic();
        Test1.staticMethod();

You can also check if it was called multiple times like this...

Test1.staticMethod();
Test1.staticMethod();
Test1.staticMethod();
PowerMockito.verifyStatic(Mockito.times(3));
Test1.staticMethod();

Upvotes: 28

Related Questions