Is it possible to use partial mocking for private static methods in PowerMock?

前端 未结 3 1746
星月不相逢
星月不相逢 2020-12-08 07:55

From the examples on the PowerMock homepage, I see the following example for partially mocking a private method with Mockito:

@RunWith(PowerMockRunner.class)         


        
相关标签:
3条回答
  • 2020-12-08 08:02

    In general, only use static mocking for classes that are beyond your control (e.g. java.io.File). Since DataProvider and readFile are your own, refactor DataProvider into a proper class (i.e. make its methods non-static), pull out readFile into a helper object and then mock that. See this answer https://stackoverflow.com/a/8819339/116509.

    0 讨论(0)
  • 2020-12-08 08:03

    Test class:

    @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<String> theData = DataProvider.getData();
            assertEquals("ohai", theData.get(0));
            assertEquals("kthxbye", theData.get(1));
        }
    
    }
    

    Class being tested (basically yours):

    public class DataProvider {
    
        public static List<String> getData() {
            try {
                return readFile();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        private static List<String> readFile() throws IOException {
            File file = new File("/some/path/to/file");
            return readLines(file, Charset.forName("utf-8"));
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 08:08

    After doing a bit more research, it seems that PowerMockito.spy() and PowerMockito.doReturn() are what is required here:

    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<String> mockData = new ArrayList<String>();
        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);
        }
    
    }
    

    For further details and the complete code listing, check out my blog post here: https://richashworth.com/post/turbocharge-your-mocking-framework-with-powermock/

    0 讨论(0)
提交回复
热议问题