使用 java 个所有者 aeonbits 进行测试
Testing with java owner aeonbits
我一直在使用 java OWNER 进行基于 属性 的配置。
我创建了一个静态方法
public static final ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
并且我在需要 conf 的任何地方导入 class。
不用说,单元测试就是一个PITA。我找不到覆盖配置中值的好方法。
我想避免在每个 class 中将配置作为依赖项传递。
它增加了很多冗长,从设计的角度来看没有意义。
同样适用于在每个 class
中调用配置工厂
ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
你有什么建议吗?有最佳实践吗?
两件事:
您可以创建一个 class 来提供属性并且所有用户都使用它:
public class PropertiesAccessor {
private static MyConfiguration mMyConfig = ConfigFactory.create(MyConfiguration.class);
private PropertiesAccessor()
// No need to allow instantiation of this class
}
/**
* Get properties for this application
*
* @return Properties
*/
public static MyConfiguration getProperties() {
return mMyConfig;
}
// for unit testing
@VisibleForTesting
public static void setProperties(MyConfiguration config) {
mMyConfig = config;
}
}
现在,任何需要 属性 的地方都可以使用这个静态方法
PropertiesAccessor.getProperties()
注意有一个测试方法,setProperties()。有多种使用此方法的方法。您可以创建一个测试 属性 文件,加载它,然后调用 setProperties() 方法。我喜欢这样的实用方法:
public static void initProperties(String fileName) {
Properties testProperties = new Properties();
File file = new File(fileName);
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
testProperties.load(stream);
} catch (IOException e) {
// Log or whatever you want to do
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Log or whatever you want to do;
}
MyConfiguration config = ConfigFactory.create(MyConfiguration.class, testProperties);
PropertiesAccessor.setProperties(config);
}
然后,您可以拥有各种属性文件。
或者,如果您只想设置一些属性,请执行以下操作:
Properties testProperties = new Properties();
testProperties.setProperty("key1", "data1");
testProperties.setProperty("key2", "data2");
final MyConfiguration myConfig = ConfigFactory.create(MyConfiguration.class, testProperties);
PropertiesAccessor.setProperties(myConfig);
Needless to say, unit testing is a PITA. I couldn't find a good way of override the values in the configuration.
您可以有 Mutable 个配置对象。阅读手册时没有 PITA。
但还有更好的方法。
当您知道 SOLID principles。
时,接口非常容易测试和处理。
import static org.mockito.Mockito.*;
MyConfig cfg = mock(MyConfig.class); // mock object
when(cfg.myConfigurationThing()).thenReturn("whateverYourObjectNeeds");
ObjectThatYouNeedToTest targetObject =
new ObjectThatYouNeedToTest(cfg); // Dependency Injection
// see: http://wiki.c2.com/?ConstructorInjection
assertEquals("expected result", targetObject.whateverYouNeedToTest());
// then you can also verify interactions:
verify(cfg, times(1)).myConfigurationThing();
上面的代码片段显示了一个 Mockito 示例,但是还有很多类似的测试框架。
检查什么Mock Objects are, what is Dependency Injection and Interface Segregation。
I would like to avoid passing the config as a dependency in every class.
如果您的对象需要配置,您应该将配置传递给您的对象。事情本该如此。
如果它很冗长,则说明您的应用程序设计中有些地方需要修改。例如,您选择在 class 中有一个带有静态成员的单例,这就是 not very good,特别是用于测试。
Same applies for calling the config factory in every class
在每个 class 中调用配置工厂,这是个坏主意。也许您可以将您的配置文件拆分为许多特定于组件的配置文件。那是一种方式(我的方式)。
但是如果你需要一个巨大的配置文件(这不是我最喜欢的方法),你的配置接口不需要遵循相同的结构:你可以有多个组件配置接口从同一个文件中读取:如果你使用热重载,这不是最好的,我可能可以做更多的事情来模块化嵌套配置接口树中的配置对象。
但是,嘿,我是在业余时间自己做的,而且我免费分享了它;如果人们做事的方式与我不同,他们需要我支持他们的工作方式,也许他们可以支持开发,贡献好的代码,或者雇用我的时间来改进它。
对不起 PITA。
我一直在使用 java OWNER 进行基于 属性 的配置。
我创建了一个静态方法
public static final ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
并且我在需要 conf 的任何地方导入 class。
不用说,单元测试就是一个PITA。我找不到覆盖配置中值的好方法。
我想避免在每个 class 中将配置作为依赖项传递。 它增加了很多冗长,从设计的角度来看没有意义。 同样适用于在每个 class
中调用配置工厂ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
你有什么建议吗?有最佳实践吗?
两件事:
您可以创建一个 class 来提供属性并且所有用户都使用它:
public class PropertiesAccessor { private static MyConfiguration mMyConfig = ConfigFactory.create(MyConfiguration.class); private PropertiesAccessor() // No need to allow instantiation of this class } /** * Get properties for this application * * @return Properties */ public static MyConfiguration getProperties() { return mMyConfig; } // for unit testing @VisibleForTesting public static void setProperties(MyConfiguration config) { mMyConfig = config; } }
现在,任何需要 属性 的地方都可以使用这个静态方法
PropertiesAccessor.getProperties()
注意有一个测试方法,setProperties()。有多种使用此方法的方法。您可以创建一个测试 属性 文件,加载它,然后调用 setProperties() 方法。我喜欢这样的实用方法:
public static void initProperties(String fileName) { Properties testProperties = new Properties(); File file = new File(fileName); FileInputStream stream = null; try { stream = new FileInputStream(file); testProperties.load(stream); } catch (IOException e) { // Log or whatever you want to do } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // Log or whatever you want to do; } MyConfiguration config = ConfigFactory.create(MyConfiguration.class, testProperties); PropertiesAccessor.setProperties(config); }
然后,您可以拥有各种属性文件。
或者,如果您只想设置一些属性,请执行以下操作:
Properties testProperties = new Properties(); testProperties.setProperty("key1", "data1"); testProperties.setProperty("key2", "data2"); final MyConfiguration myConfig = ConfigFactory.create(MyConfiguration.class, testProperties); PropertiesAccessor.setProperties(myConfig);
Needless to say, unit testing is a PITA. I couldn't find a good way of override the values in the configuration.
您可以有 Mutable 个配置对象。阅读手册时没有 PITA。
但还有更好的方法。
当您知道 SOLID principles。
时,接口非常容易测试和处理。import static org.mockito.Mockito.*;
MyConfig cfg = mock(MyConfig.class); // mock object
when(cfg.myConfigurationThing()).thenReturn("whateverYourObjectNeeds");
ObjectThatYouNeedToTest targetObject =
new ObjectThatYouNeedToTest(cfg); // Dependency Injection
// see: http://wiki.c2.com/?ConstructorInjection
assertEquals("expected result", targetObject.whateverYouNeedToTest());
// then you can also verify interactions:
verify(cfg, times(1)).myConfigurationThing();
上面的代码片段显示了一个 Mockito 示例,但是还有很多类似的测试框架。
检查什么Mock Objects are, what is Dependency Injection and Interface Segregation。
I would like to avoid passing the config as a dependency in every class.
如果您的对象需要配置,您应该将配置传递给您的对象。事情本该如此。 如果它很冗长,则说明您的应用程序设计中有些地方需要修改。例如,您选择在 class 中有一个带有静态成员的单例,这就是 not very good,特别是用于测试。
Same applies for calling the config factory in every class
在每个 class 中调用配置工厂,这是个坏主意。也许您可以将您的配置文件拆分为许多特定于组件的配置文件。那是一种方式(我的方式)。
但是如果你需要一个巨大的配置文件(这不是我最喜欢的方法),你的配置接口不需要遵循相同的结构:你可以有多个组件配置接口从同一个文件中读取:如果你使用热重载,这不是最好的,我可能可以做更多的事情来模块化嵌套配置接口树中的配置对象。
但是,嘿,我是在业余时间自己做的,而且我免费分享了它;如果人们做事的方式与我不同,他们需要我支持他们的工作方式,也许他们可以支持开发,贡献好的代码,或者雇用我的时间来改进它。
对不起 PITA。