最佳做法:如何在运行时设置配置文件以进行测试

时间:2019-06-12 08:28:20

标签: java

作为一项家庭作业(我是初学者),我不得不编写一个访问数据库的Java程序(PostgreSQL)。该程序可以例如插入新用户,增加某些字段等,而我具有诸如addUser(User t),deleteUser(User t)等方法。

我也有使用junit5编写的测试方法。对于测试,我使用“测试”数据库,与“工作”数据库分开。打开两个数据库的坐标(数据库名称,密码等)存储在两个名为config.properties和config.test.properties的文件中,这些文件在运行时选择。

我现在所拥有的是使用布尔标志变量的这些代码:

    public class UserDao {
    public boolean isTestMode = false; 

    public Connection getConnection() {

        if (this.isTestMode) {
            input = cl.getResourceAsStream("config.test.properties");
        } else {
            input = cl.getResourceAsStream("config.properties");
        }
        ...
    }
}

然后在我的测试方法中,像这样设置标志:

        void testAddUser() {
        UserDao dao = new UserDao();
        dao.isTestMode = true;
        ...
        }

在常规的非测试方法中,我没有设置isTestMode,因此它保持其默认值(false)并使用config.properties。 我的方法行得通,但是我的教练告诉我,做这样的事情是不好的做法,我应该更改它,例如(他建议)进行依赖注入。我不太确定如何进行。 我可以将configFilename设为一个类变量,然后向UserDao类中添加一个接受文件名的新构造函数,如下所示:

public class UserDao {
private String configFilename = "config.properties"; 

public UserDao() {
}

public UserDao(String filename) {
    this();
    this.configFilename = filename;
}

public Connection getConnection() {

    input = cl.getResourceAsStream(this.configFilename);
    ...
    }

}

然后在测试方法中,我使用新的构造函数UserDao(“ config.test.properties”)

(我认为更好)的一种变体是引入一个构造函数,该构造函数接受布尔isTestMode并相应地设置configFilename(我既不需要也不希望在构造函数中指定 any 文件名的灵活性)。但从本质上讲,这与我原来的方法相同,但我被告知要更改。而且,那里没有依赖注入...在这种情况下,最佳实践是什么?任何建议都将受到欢迎!

2 个答案:

答案 0 :(得分:0)

在应用程序中,在创建UserDao的实例时使用默认构造函数,在文件的junit传递名称中:

new UserDao("config.test.properties");

private final String configFilename; 

public UserDao() {
  this("config.properties");
}

public UserDao(String filename) {
    this.configFilename = filename;
}

答案 1 :(得分:0)

传递参数可以看作是琐碎的依赖注入。

关于Java:为configFilename设置默认值时,您可以看到它是您在应用程序中使用的约定。

您的班级不需要那个。而且,如果您避免这种约定,那么您将免费获得不变性。例如,您可以执行以下操作:

    public class UserDao {


    private final String configFilename;

    public UserDao(String filename) {
        this.configFilename = filename;
    }

    public Connection getConnection() {

        input = cl.getResourceAsStream(this.configFilename);
    ...
    }

}

UserDao可以由您的测试类或主类以相同的方式使用。

使用您的解决方案,您可能会交付永远不会在生产环境中运行的代码(isTestModetrue的分支),这不是一个好习惯。该代码在生产中可能被视为无效代码。