java - 如何使用 JUnit 中的公共(public)方法测试私有(private)字段设置为提供的值?

标签 java junit4

我有一个类:

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

最佳答案

在这里,您断言 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;
}

通过这种方式,您可以直接断言字段值。

关于java - 如何使用 JUnit 中的公共(public)方法测试私有(private)字段设置为提供的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44364223/

相关文章:

java - JUnit 理论和参数化测试之间的区别

java - JScrollpane 外观和感觉

sql - MS Outlook 使用 JAVA 工作

java - 哪个更好 - Integer.parseInt() 并捕获异常或在转换前使用模式验证字符串?

Java Servlet 过滤器 : I have to add headers before passing to the chain, 文档另有说明

java - 如何通过忽略空格来分割字符串

Android ExampleInstrumentedTest 口味失败

java - 我可以出于测试目的修改字段的值吗?

android - 在 Android Instrumentation TestCase 中测试 GoogleApiClient

java - JUnitCore 停止