如何使用 JUnit 中的 public 方法测试私有字段设置为提供的值?
How to test private field is set to supplied value using public method in JUnit?
我有一个 class:
public class MyEncryptor {
private StringEncryptor stringEncryptor; // this is an interface ref
public void setStringEncryptor(StringEncryptor stringEncryptorImpl) {
if(condition){
this.stringEncryptor = stringEncryptorImpl;
}
}
}
在 JUnit 中测试方法 setStringEncryptor
时,我想测试实例值 stringEncryptor
是否设置为我在参数中提供的实现?或者我测试这个方法的方式不对?
以下是我在 junit 测试方法中失败的尝试:
MyEncryptor decryptor = new MyEncryptor ();
StringEncryptor spbe = new StandardPBEStringEncryptor();
decryptor.setStringEncryptor(spbe);
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
我想测试stringEnctyptor
在junit中设置为spbe
您给出的单元测试失败,因为您试图使用 assertSame
比较 Field
实例和 StandardPBEStringEncryptor
实例。你应该做的是:assertSame(f.get(decryptor), StandardPBEStringEncryptor)
请注意,我们使用 Field::get
方法来检索字段的值,我们提供的参数是我们要检索其字段值的实例。
然而,无论如何,对 setter 类型的方法进行单元测试是多余的,只是无缘无故地增加了额外的测试代码和测试时间。
这里您断言 java.lang.reflect.Field stringEncryptor
与您为测试创建的 StringEncryptor
对象是同一个对象:
StringEncryptor spbe = new StandardPBEStringEncryptor();
...
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
这是两个截然不同且不相关的两个截然不同的对象 类。
您应该首先检索与字段关联的值:
Object value = f.get(spbe);
然后比较对象:
Assert.assertSame(value, spbe);
但无论如何我认为这不是好方法。
要测试代码,实现应该是可测试的。
只有在我们确实没有选择的情况下才应该进行反射来测试代码。
测试代码的一种自然方法是提供一种获取实际 StringEncryptor
字段的方法。
public StringEncryptor getStringEncryptor(){
return stringEncryptor;
}
通过这种方式,您可以直接断言字段值。
i want to test if instance value stringEncryptor is set to what i've
supplied in parameter as implementation? or i'm going the wrong way
for testing this method?
我认为你走错了路。只要有可能,我都会测试被测单元是否按预期进行加密,而不是具体是否设置了私有字段。您真的想测试单元功能,而不是其实现的细节。
我有一个 class:
public class MyEncryptor {
private StringEncryptor stringEncryptor; // this is an interface ref
public void setStringEncryptor(StringEncryptor stringEncryptorImpl) {
if(condition){
this.stringEncryptor = stringEncryptorImpl;
}
}
}
在 JUnit 中测试方法 setStringEncryptor
时,我想测试实例值 stringEncryptor
是否设置为我在参数中提供的实现?或者我测试这个方法的方式不对?
以下是我在 junit 测试方法中失败的尝试:
MyEncryptor decryptor = new MyEncryptor ();
StringEncryptor spbe = new StandardPBEStringEncryptor();
decryptor.setStringEncryptor(spbe);
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
我想测试stringEnctyptor
在junit中设置为spbe
您给出的单元测试失败,因为您试图使用 assertSame
比较 Field
实例和 StandardPBEStringEncryptor
实例。你应该做的是:assertSame(f.get(decryptor), StandardPBEStringEncryptor)
请注意,我们使用 Field::get
方法来检索字段的值,我们提供的参数是我们要检索其字段值的实例。
然而,无论如何,对 setter 类型的方法进行单元测试是多余的,只是无缘无故地增加了额外的测试代码和测试时间。
这里您断言 java.lang.reflect.Field stringEncryptor
与您为测试创建的 StringEncryptor
对象是同一个对象:
StringEncryptor spbe = new StandardPBEStringEncryptor();
...
Field f = MyEncryptor .class.getDeclaredField("stringEncryptor");
f.setAccessible(true);
Assert.assertSame(f, spbe);
这是两个截然不同且不相关的两个截然不同的对象 类。
您应该首先检索与字段关联的值:
Object value = f.get(spbe);
然后比较对象:
Assert.assertSame(value, spbe);
但无论如何我认为这不是好方法。
要测试代码,实现应该是可测试的。
只有在我们确实没有选择的情况下才应该进行反射来测试代码。
测试代码的一种自然方法是提供一种获取实际 StringEncryptor
字段的方法。
public StringEncryptor getStringEncryptor(){
return stringEncryptor;
}
通过这种方式,您可以直接断言字段值。
i want to test if instance value stringEncryptor is set to what i've supplied in parameter as implementation? or i'm going the wrong way for testing this method?
我认为你走错了路。只要有可能,我都会测试被测单元是否按预期进行加密,而不是具体是否设置了私有字段。您真的想测试单元功能,而不是其实现的细节。