是否可以在PowerMock中对私有静态方法使用部分模拟?

从PowerMock主页上的示例中,我看到以下示例,用于部分模拟Mockito的私有方法:

@RunWith(PowerMockRunner.class) // We prepare PartialMockClass for test because it's final or we need to mock private or static methods @PrepareForTest(PartialMockClass.class) public class YourTestCase { @Test public void privatePartialMockingWithPowerMock() { PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass()); // use PowerMockito to set up your expectation PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1"); // execute your test classUnderTest.execute(); // Use PowerMockito.verify() to verify result PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1"); } 

但是,当我们希望模拟的私有方法是静态的时,这种方法似乎不起作用。 我希望创建一个以下类的部分模拟,并使用readFile方法进行模拟:

 package org.rich.powermockexample; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.List; import static com.google.common.io.Files.readLines; public class DataProvider { public static List getData() { List data = null; try { data = readFile(); } catch (IOException e) { e.printStackTrace(); } return data; } private static List readFile() throws IOException { File file = new File("/some/path/to/file"); List lines = readLines(file, Charset.forName("utf-8")); return lines; } } 

请有人让我知道如何实现这一目标?

在做了一些研究之后,似乎PowerMockito.spy()和PowerMockito.doReturn()就是这里所需要的:

 package com.richashworth.powermockexample; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; 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 java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; @RunWith(PowerMockRunner.class) @PrepareForTest({DataProvider.class}) public class ResultsWriterTest { private static List mockData = new ArrayList(); private ResultsWriter resultsWriter; @BeforeClass public static void setUpOnce() { final String firstLine = "Line 1"; final String secondLine = "Line 2"; mockData.add(firstLine); mockData.add(secondLine); } @Before public void setUp() { resultsWriter = new ResultsWriter(); } @Test public void testGetDataAsString() throws Exception { PowerMockito.spy(DataProvider.class); PowerMockito.doReturn(mockData).when(DataProvider.class, "readFile"); final String expectedData = "Line 1\nLine 2\n"; final String returnedString = resultsWriter.getDataAsString(); assertEquals(expectedData, returnedString); } } 

测试类:

 @RunWith(PowerMockRunner.class) @PrepareForTest(DataProvider.class) public class DataProviderTest { @Test public void testGetDataWithMockedRead() throws Exception { mockStaticPartial(DataProvider.class, "readFile"); Method[] methods = MemberMatcher.methods(DataProvider.class, "readFile"); expectPrivate(DataProvider.class, methods[0]).andReturn(Arrays.asList("ohai", "kthxbye")); replay(DataProvider.class); List theData = DataProvider.getData(); assertEquals("ohai", theData.get(0)); assertEquals("kthxbye", theData.get(1)); } } 

正在测试的类(基本上是你的):

 public class DataProvider { public static List getData() { try { return readFile(); } catch (IOException e) { e.printStackTrace(); return null; } } private static List readFile() throws IOException { File file = new File("/some/path/to/file"); return readLines(file, Charset.forName("utf-8")); } } 

通常,只对您无法控制的类使用静态模拟(例如java.io.File )。 由于DataProviderreadFile是你自己的,重构DataProvider到一个合适的类(即使其方法非静态),将readFile拉出一个辅助对象,然后模拟它。 请参阅此答案https://stackoverflow.com/a/8819339/116509 。