Java 重构静态方法/静态测试字段
我有以下遗留代码:Java 重构静态方法/静态测试字段,java,testing,refactoring,static,Java,Testing,Refactoring,Static,我有以下遗留代码: public class MyLegacyClass { private static final String jndiName = "java:comp/env/jdbc/LegacyDataSource" public static SomeLegacyClass doSomeLegacyStuff(SomeOtherLegacyClass legacyObj) { // do stuff using jndiName }
public class MyLegacyClass
{
private static final String jndiName = "java:comp/env/jdbc/LegacyDataSource"
public static SomeLegacyClass doSomeLegacyStuff(SomeOtherLegacyClass legacyObj)
{
// do stuff using jndiName
}
}
此类在J2EE容器中工作
现在我想在容器外部测试这个类
最好的策略是什么?
重构基本上是允许的
允许访问LegacyDataSource(测试不必是“纯”单元测试)
编辑:不允许引入其他运行时框架。重构代码以使用依赖项注入。然后使用您喜欢的DI框架(Spring、Guice等)注入您的资源。这将使在运行时在资源对象和策略之间切换变得容易 在这种情况下,可以注入数据源
编辑:根据您的新限制,您可以通过使用策略模式在运行时设置数据源来完成相同的任务。您可能只需要使用属性文件来区分创建和提供数据源的策略。这不需要新的框架,您只需手工编写相同的基本功能即可。当在JavaEE容器之外进行测试时,我们使用ServiceLocator来提供模拟数据源。我认为最好的解决方案是将JNDI绑定到本地 遗留代码使用的jndiName如下所示:
DataSource datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(System.getProperty("driverClassName"));
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerName("localhost");
dataSource.setPort(3306);
dataSource.setDatabaseName("databasename");
因此,这里的解决方案是将本地(或您为测试数据准备的任何东西)绑定到JNDI中,如下所示:
DataSource datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(System.getProperty("driverClassName"));
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerName("localhost");
dataSource.setPort(3306);
dataSource.setDatabaseName("databasename");
然后是绑定:
Context context = new InitialContext();
context.bind("java:comp/env/jdbc/LegacyDataSource",datasource);
或者类似的,希望能对你有所帮助
祝你好运 让@Robin关于战略模式的建议更具体一点:(注意,您最初问题的公共API保持不变。) …和JUnit测试。我不太喜欢这样的安装/拆卸维护,但这是基于静态方法(或单例)的API带来的一个不幸的副作用。我喜欢这个测试的地方是它没有使用JNDI——这很好,因为(a)它运行得很快,(b)单元测试应该只测试doSomeLegacyStuff()方法中的业务逻辑,而不是测试实际的数据源。(顺便说一下,这假设测试类与MyLegacyClass位于同一个包中。)
我根据你的新限制更新了我的答案。实际上,我们有一个系统必须解决同样的问题。@Scot Bale只是在问,如果doSomeLegacyStuff绑定到用户会话,这是否会在多线程环境中导致一些竞争条件和不一致