读取/写入.properties文件的实用程序类的测试环境

时间:2017-06-21 22:46:18

标签: java io properties-file

我在一个需要在运行时根据应用程序的要求在.properties文件中读/写的类中工作。

该应用程序片段的项目结构如下:

src
  |-main
  |    |-java
  |    |    |-file
  |    |         |-FileUtil.java
  |    |
  |    |-resources
  |              |-file.properties
  |
  |-test
       |-java
       |    |-file
       |         |-FileUtilTest.java
       |
       |-resources
                 |-file.properties

因此,目标是FileUtilTest实例化FileUtil对象,调用相应的FileUtil方法并在file.properties上进行一些断言。我已成功阅读file.properties,但我不确定它是否能正确读/写src/main/resources/file.properties而不是src/test/resources/file.properties

如何确定测试方法是否会在生产环境中读取/写入正确的文件?

如果您需要有关我班级的任何额外信息,请告诉我。提前感谢您的回答。

编辑#1

这是我到目前为止的代码:

FileUtil.java

public class FileUtil {

    // File name
    static final String DATA_FILE = "file.properties";

    // Property names
    static final String CURRENT_YEAR_PROPERTY = "currentYear";
    static final String CURRENT_NUMBER_PROPERTY = "currentNumber";

    int currentYear;
    String currentNumber;
    private File file;
    private Properties properties;

    public FileUtil() {
        try {
            loadDataFile();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public String getNextNumber() {
        Integer nextInteger;
        String result = null;

        if (currentNumber != null) {
            nextInteger = Integer.parseInt(currentNumber) + 1;
            result = String.format("%08d", nextInteger);
            properties.setProperty("currentNumber", result);
        }

        return result;
    }

    // Utility method to load the current values in the class. IOE should never be thrown
    private void loadDataFile() throws IOException {
        properties = new Properties();

        ClassLoader classLoader = getClass().getClassLoader();
        file = new File(classLoader.getResource(DATA_FILE).getFile());

        properties.load(new FileInputStream(file));
        currentYear = Integer.parseInt(properties.getProperty("currentYear"));
        currentNumber = properties.getProperty("currentNumber");
        properties.store(new FileOutputStream(file), null);
    }
}

FileUtilTest.java

public class FileUtilTest {

    private FileUtil fileUtil;
    private final Logger logger = Logger.getLogger(FileUtilTest.class.getName());

    // Properties to “reset” the file in every test
    private final String INITIAL_CURRENT_YEAR = "2017";
    private final String INITIAL_CURRENT_NUMBER = "00004954";

    @Before
    public void setUp() throws FileNotFoundException {
        fileUtil = new FileUtil();
    }

    @After
    public void tearDown() throws IOException {
        fileUtil = null;
        Properties initialProperties = new Properties();
        initialProperties.put(FileUtil.CURRENT_YEAR_PROPERTY, INITIAL_CURRENT_YEAR);
        initialProperties.put(FileUtil.CURRENT_NUMBER_PROPERTY, INITIAL_CURRENT_NUMBER);

        ClassLoader classLoader = getClass().getClassLoader();
        File file = new File(classLoader.getResource(FileUtil.DATA_FILE).getFile());
        initialProperties.store(new FileOutputStream(file), null);
    }

    @Test
    public void dataFileReadCorrectly() {
        logger.log(Level.INFO, "Current year = {0}", fileUtil.currentYear);
        logger.log(Level.INFO, "Current number = {0}", fileUtil.currentNumber);

        // Testing the loadDataFile() as it’s called in the constructor 
        assertEquals(2017, fileUtil.currentYear);
        assertEquals("00004954", fileUtil.currentNumber);
    }

    @Test
    public void nextNumberObtainedCorrectly() {
        logger.log(Level.INFO, "Next number = {0}", fileUtil.getNextNumber());

        // Testing the value obtained from getNextNumber()
        assertNotNull(fileUtil.getNextNumber());
        assertEquals("00004955", fileUtil.getNextNumber());
    }

}

file.properties

currentYear=2017
currentNumber=00004954

总而言之,该类从属性文件中读取值并使用getNextNumber()计算nextNumber。用户可以调用另一个方法(尚未实现)将下一个数字写入属性文件,因此当用户需要另一个数字时,他会获得下一个数字,依此类推。当年度更改currentNumber设置为00000001currentYear更新时,我是否明确了自己的想法?

希望有助于澄清问题。

编辑#2

我忘了说:当我写这篇文章时,我没有setUp()tearDown()的身体。现在测试给了我NumberFormatException:ClassCastException: java.lang.Integer cannot be cast to java.lang.String(我试图使用INITIAL_CURRENT_YEAR作为Integer代替String

1 个答案:

答案 0 :(得分:1)

几乎可以保证它无法写入生产中的属性文件 - jar内部不可写。

最好将API构建为在InputStreamReader上运行(并写入PrintStreamWriter)并测试内存流,然后分开你的文件打开逻辑。