Using PowerMock with Spock
Asked Answered
E

3

11

I have a class with a few static methods.I need to Mock these static methods. I know PowerMock does this,but I was not able to find any tutorials/materials that shed some light on "Spock+PowerMock" integration. I prefer Spock to Junit,hence the conundrum. Is there a way of getting these 2 frameworks to play ball?Any help is much appreciated.Sample code,even more so.

Update: Current Status of the Approach

Spock behaving weirdly

Enalda answered 21/10, 2013 at 11:48 Comment(0)
C
15

I was stuck here for a while too. After searching for hours, I saw this github repo: https://github.com/kriegaex/Spock_PowerMock.

I tried adding a PowerMockRule which essentially enabled me to use PowerMock together with Spock. I had to add these dependencies. Version is at 1.5.4

   <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-module-junit4</artifactId>
      <version>${powermock.version}</version>
      <scope>test</scope>
   </dependency>

   <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4-rule</artifactId>
        <version>${powermock.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-classloading-xstream</artifactId>
        <version>${powermock.version}</version>
        <scope>test</scope>
    </dependency>

My class looks like this:

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([SomeStaticClass.class])
public class FlightFormSpec extends Specification { 

    @Rule PowerMockRule powerMockRule = new PowerMockRule();

    def "When mocking static"() {
        setup :
            PowerMockito.mockStatic(SomeStaticClass.class)

        when :
            Mockito.when(SomeStaticClass.someStaticMethod()).thenReturn("Philippines!");

        then :
            SomeStaticClass.someStaticMethod() == "Philippines!"
    }
}

Here is another resource: https://github.com/jayway/powermock/wiki/powermockrule

Corrigan answered 15/7, 2014 at 2:36 Comment(5)
Hey, you found my repo and saved me from answering this one by myself. :-)Interlingua
@Interlingua you wrote it. I almost gave up with Spock and PowerMock.Thanks for making your repo public! :)Corrigan
@Avinash: You should accept juanpaolo's answer instead of your own one stating that it does not work. I think he deserves it.Interlingua
What is the point of using Spock if we still use JUnit 4 rules and also can't overcome the verbose language of Mockito? Static method being used is actually a code smell because a static method should normally be a utility method without a side effect (so that there is no need to mock it). Also, intention behind using Spock includes using Groovy's syntax tricks (like >> to define the object returned) to make tests easier to read. If we write Mockito "when"s, "thenReturn"s, "verify"s then all we are gaining with Spock is just string names for our tests and the "setup", "when" and "then" labels.Peluso
Well, if Spock gives us the tools to handle legacy code in this way.... FWIW I mostly use Spock Mock, but find that Mockito is still a useful tool for some situations I need to test.Octaviooctavius
B
1

There is no special integration; your best bet is to try and use PowerMock "as-is". From what I remember, PowerMock used to have problems with Groovy, and I don't know if this has been solved. And if I'm not mistaken, PowerMock rewrites the byte code of test classes, so the next question is if it works with Spock. Let us know what you find.

Boothe answered 21/10, 2013 at 12:25 Comment(1)
Tried it out, I am getting a bizarre error similar to the one described here....link .Absolutely not sure whats happening here :(Enalda
S
1

Since Powermock Version 1.6.0, powermock allows the delegation of the test runner.

This allows the wrapping of the Spock test runner (Sputnik) within the PowerMock test runner framework. Sputnik will then start the test case specifications, and still allow the use of the PowerMock framework.

With JUnit4 and Powermock, I use the following template for accessing static classes.

The test class:

package mypackage;

import org.junit.runner.RunWith
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([MyStaticMethodClass.class])
class MyTestForClassTest extends Specification {

    def myStaticMethodClass

    def setup() {
        PowerMockito.mockStatic(MyStaticMethodClass.class)
        myStaticMethodClass= Mock(MyStaticMethodClass)
        PowerMockito.when(MyStaticMethodClass.getInstance()).thenReturn(myStaticMethodClass)
    }

    @Unroll
    def "#TestCase policy RF210 triggered"() {
    given: "a product list for the policy"
    myStaticMethodClass.someInstanceMethod() >> "my return value"
    classUnderTest = new ClassUnderTest()
    ...

The dependencies

  <dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
  </dependency>

    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-core</artifactId>
        <version>1.3-groovy-2.5</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib-nodep</artifactId>
        <version>3.3.0</version>
        <scope>test</scope>
    </dependency>
Sherd answered 9/9, 2019 at 4:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.