jeudi 26 décembre 2019

Java - How to swap a resource file path for a test file during unit testing?

I have a resource file which has some settings. I have a ResourceLoader class which loads the settings from this file. This class is currently an eagerly instantiated singleton class. As soon as this class loads, it reads the settings from the file (file path stored as a constant field in another class). Some of these settings are not suitable for unit tests. E.g. I have thread sleep time in this file, which may be hours for production code but I'd like it to be a couple of milliseconds for unit tests. So I have another test resource file which has a different set of values. My question is how do I go about swapping the main resource file with this test file during unit testing? The project is a maven project and I'm using testng as the testing framework. These are some of the approaches I've been thinking about but none of them seem ideal:

  1. Use @BeforeSuite and modify the FilePath constant variable to point to the test file and use @AfterSuite to point it back to the original file. This seems to be working but I think because the ResourceLoader class is eagerly instantiatied, there is no guarantee that the @BeforeSuite method will always execute before the ResourceLoader class is loaded and hence old properties may be loaded before the file path is changed. Although most compilers load a class only when it is required, I'm not sure if this is a java specification requirement. So in theory this may not work for all java compilers.

  2. Pass the resource file path as a command line argument. I can add the test resource file path as command line argument in the surefire configuration in the pom. This seems a bit excessive.

  3. Use the approach in 1. and make ResourceLoader lazy instantiated. This guarantees that if @BeforeMethod is called before the first call to ResourceLoader.getInstance().getProperty(..), ResourceLoader will load the correct file. This seems to be better than the first 2 approaches but I think making a singleton class lazy instantiated makes it ugly as I can't use a simple pattern like making it an enum and such (as is the case with eager instantiation).

This seems like a common scenario, what is the most common way of going about it?

Aucun commentaire:

Enregistrer un commentaire