我有一个班级:
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
答案 0 :(得分:1)
您提供的单元测试失败,因为您尝试使用Field
比较StandardPBEStringEncryptor
实例和assertSame
实例。你应该做的是:assertSame(f.get(decryptor), StandardPBEStringEncryptor)
请注意,我们使用Field::get
方法检索字段的值,我们给出的参数是我们要检索其字段值的实例。
然而,无论如何,单元测试setter类型方法是多余的,只是无缘无故地添加额外的测试代码和测试时间。
答案 1 :(得分:0)
在此断言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;
}
通过这种方式,您可以直接断言字段值。
答案 2 :(得分:0)
我想测试实例值stringEncryptor是否设置为我的 作为实现参数提供?或者我走错了路 用于测试此方法?
我认为你走错了路。只要有可能,我会测试被测单元是否按预期进行加密,而不是特别设置私有字段。你真的想测试单元功能,而不是它的实现细节。