example java unit-testing mockito powermock

java - example - ¿Es posible usar burlas parciales para métodos estáticos privados en PowerMock?



powermock example (3)

Clase de prueba:

@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)); } }

Clase que está siendo probada (básicamente la suya):

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")); } }

De los ejemplos en la página de inicio de PowerMock , veo el siguiente ejemplo para burlarse parcialmente de un método privado con 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"); }

Sin embargo, este enfoque no parece funcionar cuando el método privado que queremos simular es estático. Deseo crear un simulacro parcial de la clase inferior, con el método readFile burlado:

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<String> getData() { List<String> data = null; try { data = readFile(); } catch (IOException e) { e.printStackTrace(); } return data; } private static List<String> readFile() throws IOException { File file = new File("/some/path/to/file"); List<String> lines = readLines(file, Charset.forName("utf-8")); return lines; } }

Por favor, ¿podría alguien decirme cómo se puede lograr esto?


Después de investigar un poco más, parece que PowerMockito.spy () y PowerMockito.doReturn () son lo que se requiere aquí:

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); } }


En general, solo use burlas estáticas para las clases que están más allá de su control (por ejemplo, java.io.File ). Como DataProvider y readFile son suyos, refactorice DataProvider en una clase adecuada (es decir, haga que sus métodos no sean estáticos), extraiga readFile en un objeto auxiliar y luego simule eso. Vea esta respuesta https://.com/a/8819339/116509 .