模拟私有方法
Mocking a private method
我正在尝试模拟一个在内部调用私有方法的方法。此私有方法使用 classloader.getclass
方法读取文件并填充一个列表,该列表是 class 的静态变量。我尝试了所有可能的方法来模拟这个私有方法,但它似乎不起作用。
class TestLoad {
private static List <String> myList = new ArrayList <String> ();
private static final String filename = "/myfile.txt";
public XYZ generateList(Abc abc) throws Exception {
populateList();
}
private populateList() {
ClassLoader classLoader = TestLoad.class.getClassLoader();
File listfile = new File(classLoader.getResource(
filename).getFile());
List <String> localList = new ArrayList <String> ();
try (Scanner scanner = new Scanner(listfile)) {
while (scanner.hasNextLine()) {
String text = scanner.nextLine();
localList.add(text.trim());
}
scanner.close();
} catch (IOException e) {}
return localList;
}
}
我正在尝试模拟 populateList()
但控件一直进入该方法。我通过 mockito 和 powermock 尝试了网上几乎所有的选项,但它似乎并不 work.My Junit 如下
Class 开始有@RunWith(PowerMockRunner.class)
@PrepareForTest(TestLoad.class)
ArrayList testList = new ArrayList();
testList.add("00"); TestLoad 实例 = PowerMock.createPartialMock(TestLoad.class,"populateList");
PowerMock.expectPrivate(实例, "populateList").andReturn(测试列表);
PowerMock.replay(实例);
以下日志供参考:
java.lang.IllegalStateException: Failed to transform class with name com.xyz.TestLoad. Reason: java.io.IOException: invalid constant type: 18 at 17
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:266)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:145)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.(JUnit4TestSuiteChunkerImpl.java:61)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.(PowerMockRunner.java:34)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
您的测试代码看起来像是在使用 PowerMock EasyMock。
但是您的 post 也被标记为 mockito 和 powermockito。
我正在使用 powermockito 给出以下解决方案。
主要Javaclass:
public class TestLoad {
private static List<String> myList = new ArrayList<String>();
private static final String filename = "/myfile.txt";
public List<String> generateList(Abc abc) throws Exception {
System.out.println("generateList method is called");
return populateList();
}
private List<String> populateList() {
System.out.println("populateList method is called");
ClassLoader classLoader = TestLoad.class.getClassLoader();
File listfile = new File(classLoader.getResource(filename).getFile());
// Read listfile and build localList logic here
List<String> localList = new ArrayList<String>();
return localList;
}
}
测试Javaclass
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@PrepareForTest(TestLoad.class)
@RunWith(PowerMockRunner.class)
public class TestLoadTest {
@Test
public void testPrivateMethod() throws Exception{
List<String> testList = new ArrayList<String>();
testList.add("00");
TestLoad mockInstance = PowerMockito.spy(new TestLoad());
PowerMockito.doReturn(testList).when(mockInstance, "populateList");
List<String> outputList = mockInstance.generateList(new Abc());
System.out.println("test output:" + outputList);
PowerMockito.verifyPrivate(mockInstance, Mockito.times(1)).invoke("populateList");
}
}
控制台输出:
generateList method is called
test output:[00]
经过大量研究,我找到了解决方案。我们需要在 pom.xml 中添加以下依赖项以防止出现此错误... **
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.2-GA</version>
</dependency>
**
我正在尝试模拟一个在内部调用私有方法的方法。此私有方法使用 classloader.getclass
方法读取文件并填充一个列表,该列表是 class 的静态变量。我尝试了所有可能的方法来模拟这个私有方法,但它似乎不起作用。
class TestLoad {
private static List <String> myList = new ArrayList <String> ();
private static final String filename = "/myfile.txt";
public XYZ generateList(Abc abc) throws Exception {
populateList();
}
private populateList() {
ClassLoader classLoader = TestLoad.class.getClassLoader();
File listfile = new File(classLoader.getResource(
filename).getFile());
List <String> localList = new ArrayList <String> ();
try (Scanner scanner = new Scanner(listfile)) {
while (scanner.hasNextLine()) {
String text = scanner.nextLine();
localList.add(text.trim());
}
scanner.close();
} catch (IOException e) {}
return localList;
}
}
我正在尝试模拟 populateList()
但控件一直进入该方法。我通过 mockito 和 powermock 尝试了网上几乎所有的选项,但它似乎并不 work.My Junit 如下
Class 开始有@RunWith(PowerMockRunner.class) @PrepareForTest(TestLoad.class) ArrayList testList = new ArrayList(); testList.add("00"); TestLoad 实例 = PowerMock.createPartialMock(TestLoad.class,"populateList"); PowerMock.expectPrivate(实例, "populateList").andReturn(测试列表); PowerMock.replay(实例);
以下日志供参考:
java.lang.IllegalStateException: Failed to transform class with name com.xyz.TestLoad. Reason: java.io.IOException: invalid constant type: 18 at 17 at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:266) at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180) at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:145) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40) at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.(JUnit4TestSuiteChunkerImpl.java:61) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.(AbstractCommonPowerMockRunner.java:32) at org.powermock.modules.junit4.PowerMockRunner.(PowerMockRunner.java:34) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
您的测试代码看起来像是在使用 PowerMock EasyMock。 但是您的 post 也被标记为 mockito 和 powermockito。
我正在使用 powermockito 给出以下解决方案。
主要Javaclass:
public class TestLoad {
private static List<String> myList = new ArrayList<String>();
private static final String filename = "/myfile.txt";
public List<String> generateList(Abc abc) throws Exception {
System.out.println("generateList method is called");
return populateList();
}
private List<String> populateList() {
System.out.println("populateList method is called");
ClassLoader classLoader = TestLoad.class.getClassLoader();
File listfile = new File(classLoader.getResource(filename).getFile());
// Read listfile and build localList logic here
List<String> localList = new ArrayList<String>();
return localList;
}
}
测试Javaclass
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@PrepareForTest(TestLoad.class)
@RunWith(PowerMockRunner.class)
public class TestLoadTest {
@Test
public void testPrivateMethod() throws Exception{
List<String> testList = new ArrayList<String>();
testList.add("00");
TestLoad mockInstance = PowerMockito.spy(new TestLoad());
PowerMockito.doReturn(testList).when(mockInstance, "populateList");
List<String> outputList = mockInstance.generateList(new Abc());
System.out.println("test output:" + outputList);
PowerMockito.verifyPrivate(mockInstance, Mockito.times(1)).invoke("populateList");
}
}
控制台输出:
generateList method is called
test output:[00]
经过大量研究,我找到了解决方案。我们需要在 pom.xml 中添加以下依赖项以防止出现此错误... **
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.2-GA</version>
</dependency>
**