访问私有字段以进行 junit 测试
Access a private field for a junit test
我正在尝试从 class 初始化一个私有字段,以便对其方法进行单元测试。为此,我正在使用反射,但我总是收到 IllegalArgumentException,我不明白我做错了什么。
我的代码看起来像这样:
public class MyClass {
private BufferedReader reader;
public void methodToTest(){
doSomethingwith(reader);
}
}
public class testClass {
@Test
public void testMethod() {
Field reader = MyClass.class.getDeclaredField("reader");
reader.setAccessible(true);
StringReader stringReader = new StringReader("some string");
BufferedReader readerToSet = new BufferedReader(stringReader);
reader.set(readerToSet, readerToSet);
MyClass instance = new MyClass();
instance.methodToTest();
}
}
我在尝试 运行 测试时遇到此错误:
Can not set java.io.BufferedReader field MyClass.receiveReader to java.io.BufferedReader
我还尝试从 class 获取字段的值并设置给阅读器。但是值 returns null 和我仍然收到相同的错误消息。
知道如何初始化字段以便测试该方法吗?
您必须先实例化对象,然后您才能设置它的字段! (并且您拼错了 BufferedReader 参考。)
Field reader = MyClass.class.getDeclaredField("reader");
reader.setAccessible(true);
MyClass mc = new MyClass();
StringReader stringReader = new StringReader("some string");
BufferedReader readerToSet = new BufferedReader(stringReader);
reader.set(mc, readerToSet);
mc.methodToTest();
@kocko 的回答在大多数情况下都是正确的。但是,如果您不想显示实施细节,您可以不为您的字段设置访问级别修饰符(default
访问级别)。
因此在您的情况下,字段声明应如下所示:
public class MyClass {
BufferedReader reader;
...
}
然后确保您的测试与您的代码位于同一个包中,但在 test
目录中。如果一切正常,您将能够在没有任何黑客攻击的情况下访问它。
注意:default
访问级别意味着该事物仅在 class 和包内可见。
您可以为此使用 Mockito (org.mockito.internal.util.reflection.Whitebox)
Whitebox.setInternalState(object, "fieldName", fieldValue);
使用apache.commons.lang3
import org.apache.commons.lang3.reflect.FieldUtils;
FieldUtils.writeField(myObject, "anyProperty", 420/*any value*/, true);
FieldUtils.readField(myObject, "anyProperty", true);
如果您使用 spring,您也可以使用 spring-test。
import org.springframework.test.util.ReflectionTestUtils;
ReflectionTestUtils.setField(notificationService, "timeToLive", 90L);
我正在尝试从 class 初始化一个私有字段,以便对其方法进行单元测试。为此,我正在使用反射,但我总是收到 IllegalArgumentException,我不明白我做错了什么。
我的代码看起来像这样:
public class MyClass {
private BufferedReader reader;
public void methodToTest(){
doSomethingwith(reader);
}
}
public class testClass {
@Test
public void testMethod() {
Field reader = MyClass.class.getDeclaredField("reader");
reader.setAccessible(true);
StringReader stringReader = new StringReader("some string");
BufferedReader readerToSet = new BufferedReader(stringReader);
reader.set(readerToSet, readerToSet);
MyClass instance = new MyClass();
instance.methodToTest();
}
}
我在尝试 运行 测试时遇到此错误:
Can not set java.io.BufferedReader field MyClass.receiveReader to java.io.BufferedReader
我还尝试从 class 获取字段的值并设置给阅读器。但是值 returns null 和我仍然收到相同的错误消息。
知道如何初始化字段以便测试该方法吗?
您必须先实例化对象,然后您才能设置它的字段! (并且您拼错了 BufferedReader 参考。)
Field reader = MyClass.class.getDeclaredField("reader");
reader.setAccessible(true);
MyClass mc = new MyClass();
StringReader stringReader = new StringReader("some string");
BufferedReader readerToSet = new BufferedReader(stringReader);
reader.set(mc, readerToSet);
mc.methodToTest();
@kocko 的回答在大多数情况下都是正确的。但是,如果您不想显示实施细节,您可以不为您的字段设置访问级别修饰符(default
访问级别)。
因此在您的情况下,字段声明应如下所示:
public class MyClass {
BufferedReader reader;
...
}
然后确保您的测试与您的代码位于同一个包中,但在 test
目录中。如果一切正常,您将能够在没有任何黑客攻击的情况下访问它。
注意:default
访问级别意味着该事物仅在 class 和包内可见。
您可以为此使用 Mockito (org.mockito.internal.util.reflection.Whitebox)
Whitebox.setInternalState(object, "fieldName", fieldValue);
使用apache.commons.lang3
import org.apache.commons.lang3.reflect.FieldUtils;
FieldUtils.writeField(myObject, "anyProperty", 420/*any value*/, true);
FieldUtils.readField(myObject, "anyProperty", true);
如果您使用 spring,您也可以使用 spring-test。
import org.springframework.test.util.ReflectionTestUtils;
ReflectionTestUtils.setField(notificationService, "timeToLive", 90L);