Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重构静态方法/静态测试字段_Java_Testing_Refactoring_Static - Fatal编程技术网

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绑定到用户会话,这是否会在多线程环境中导致一些竞争条件和不一致