How to Make Spock and PowerMock Work Together

A workaround for NullPointerException thrown in PowerMockRule.

WZ
2 min readJun 1, 2017

Spock is a testing and specification framework. There are many features provided by Spock, data-driven, mocking, stubbing, verification. The biggest benefit of using Spock is helping you keep test codes structure more clear. Spock can make your tests more readable and enforce you design test in given-when-then pattern. This is the main reason I choose Spock to write test.

Spock has build-in mocking and stubbing capabilities, but it still can’t mock static methods. To do this, Spock need to work with other mocking framework, like PowerMock.

Spock has its own JUnit runner which is named Sputnik and used in abstract class - Specification. To introduce PowerMock into Specification, all the samples found in network use JUnit rule as below.

It was fine in older version of PowerMock. But there is an issue when using recent version of Mockito and PowerMock. A NullPointerException is thrown from PowerMockRule.

import org.junit.Rule
import org.mockito.Mockito
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.rule.PowerMockRule
import spock.lang.Specification
@PrepareForTest([TestClass.class])
class MockStaticMethodSpec extends Specification {
@Rule
PowerMockRule mPowerMockRule = new PowerMockRule();
def "Test static method"() {
setup:
PowerMockito.mockStatic(TestClass.class)
when:
Mockito.when(TestClass.staticMethod())
.thenReturn("Verify String")
then:
TestClass.staticMethod() == "Verify String"
}
}

It is not good and I don’t want to back to JUnit + Mock framework solution after using Spock. Unfortunately, I could’t find any solution in network. It means I need to dig deeper about how PowerMock work, So I went to PowerMock official site.

I found this in official document of PowerMock:

Since version 1.6.0 PowerMock has support for delegating the test execution to another JUnit runner without using a JUnit Rule. This leaves the actual test-execution to another runner of your choice. For example tests can delegate to “SpringJUnit4ClassRunner”, “Parameterized” or the “Enclosed” runner.

Since PowerMock can delegate another JUnit runner, we can wrap Sputnik by PowerMockRunner. Then Sputnik will start test cases in specification and the features of PowerMock can be used in test code.

Here is the workaround to solve the NullPointerException issue:

import org.junit.runner.RunWith
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.powermock.modules.junit4.PowerMockRunnerDelegate
import org.spockframework.runtime.Sputnik
import spock.lang.Specification
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(Sputnik.class)
@PrepareForTest([TestClass.class])
class MockStaticMethodSpec extends Specification {
def "Test static method"() {
setup :
PowerMockito.mockStatic(TestClass.class)
when :
Mockito.when(TestClass.staticMethod())
.thenReturn("Verify String")
then :
TestClass.staticMethod() == "Verify String"
}
}

There are some messages after running tests, but I don’t care because it works!

--

--