简体   繁体   中英

PowerMock mock static method from abstract class

I've seen one other example of this question on Stack, but no answers. Can anyone tell me based on experience (or any other esoteric means) if this is even possible to do? I've followed all of the examples I could find of mocking static methods I could find, but haven't found one that works for static methods in abstract classes. Two methods fail with MissingMethodInvocationException:

File[] files = {goodFile, badFile};
PowerMockito.mockStatic(AbstractFileImporter.class);

// fails with MissingMethodInvocationException
PowerMockito.when(AbstractFileImporter.getFiles(".")).thenReturn(files);

And:

// fails with MissingMethodInvocationException
BDDMockito.given(AbstractFileImporter.getFiles(".")).willReturn(files);

Whereas this method fails with IllegalStateException:

// fails with IllegalStateException
expect(AbstractFileImporter.getFiles(".")).andReturn(files);

I'm pretty new to mocking, so any advice or good site links to use as resources while trudging through all of this would be really helpful. By the way, I do have some leeway with regard to refactoring, but not on using different tools/utilities, so I'm stuck with Mockito/PowerMock and TestNG.

Okay, I tried to convert my example to TestNG and it worked for me after following the example at https://code.google.com/p/powermock/wiki/TestNG_usage .

I get the MissingMethodInvocationException you mentioned when I'm omitting the required test class annotation @PrepareForTest(AbstractAnimal.class) .

I'm using eclipse 4.4.1 with the TestNG plugin version 6.8.6.

See below for my converted example and the dependencies. Also, notice the extension of PowerMockTestCase . I did not change the sample class AbstractAnimal .

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.Assert;
import org.testng.annotations.Test;

@PrepareForTest(AbstractAnimal.class)
public class AbstractAnimalTest extends PowerMockTestCase {

    @Test
    public void shouldGetMockedHello() {
        PowerMockito.mockStatic(AbstractAnimal.class);
        PowerMockito.when(AbstractAnimal.getHello()).thenReturn("Hello mocked animal world!");

        String greetings = AbstractAnimal.getHello();
        Assert.assertTrue(greetings.equals("Hello mocked animal world!"));
    }

}

Dependendencies (I tried to use your versions):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.gnollix.stackoverflow</groupId>
    <artifactId>mock-static-abstract</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.8</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-testng</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.5.6</version>
        </dependency>
    </dependencies>

</project>

Resolved dependencies:

解决的依赖关系

Hope that's useful!

I tried mocking a static method in a simple abstract class and it worked.

I used https://code.google.com/p/powermock/wiki/MockitoUsage13 for usage examples.

Here is my sample code:

Abstract class with static method:

public abstract class AbstractAnimal {

    public static String getHello() {
        return "Hello animal world!";
    }

}

Test class for mocking:

import org.junit.Assert;
import org.junit.Test;
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;

@RunWith(PowerMockRunner.class)
@PrepareForTest(AbstractAnimal.class)
public class AbstractAnimalTest {

    @Test
    public void shouldGetMockedHello() {
        PowerMockito.mockStatic(AbstractAnimal.class);
        Mockito.when(AbstractAnimal.getHello()).thenReturn("Hello mocked animal world!");

        String greetings = AbstractAnimal.getHello();
        Assert.assertTrue("Hello mocked animal world!".equals(greetings));
    }

}

POM file in case you are interested in the concrete dependencies:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.gnollix.stackoverflow</groupId>
    <artifactId>mock-static-abstract</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <powermock.version>1.6.1</powermock.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <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-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM