【问题标题】:Testing ServiceLocator using JUnit使用 JUnit 测试 ServiceLocator
【发布时间】:2009-11-09 00:56:31
【问题描述】:

这是我的previous question 的后续问题。

我正在尝试为我的 ServiceLocator 类编写测试用例,但它给了我以下错误:

com/iplanet/ias/admin/common/ASException
java.lang.NoClassDefFoundError: com/iplanet/ias/admin/common/ASException
        at java.lang.ClassLoader.defineClass1(Native Method)

我的测试用例:

public void testServiceLocator () throws UivException, NamingException
{
    DataSource ds = ServiceLocator.getInstance().getDataSource("jdbc/RSRC/my/mydb");
    //I have not put any assert statements because i know above line is failing
}

上述代码在getInstance() 方法上失败,如下所示:

static public ServiceLocator getInstance() throws UivException {
    try {
        if (me == null) {
          synchronized(ServiceLocator.class) {
            me = new ServiceLocator();
          }
        }
        return me;
    }
    catch (UivException e) {
          throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                                 ErrorCode.SERVICE_LOCATOR_LOOKUP_ERROR,
                                 e.getMessage());
    }
}

我知道这个ServiceLocator 工作正常,因为当我从前端测​​试我的应用程序时没有问题。我写这个测试用例的唯一原因是因为我想测试我的DAO。而我要测试我的 DAO ServiceLocator 必须工作(来自 JUnit)。

我不知道如何处理错误消息。有没有人想建议一些我可以尝试但希望能奏效的东西?

编辑:ServiceLocator 构造函数

private ServiceLocator() throws UivException  {
    try {
        ic = new InitialContext();
        // System.out.println("Created the Initial Context");
        cache = Collections.synchronizedMap(new HashMap());
    }
    catch (NamingException ne) {
        throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                               0, ne.getMessage());
    }
    catch (NullPointerException e) {
          throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                                 0, e.getMessage());
    }
}

【问题讨论】:

    标签: java junit jndi service-locator


    【解决方案1】:

    其实错误很明显:java.lang.NoClassDefFoundError: com/iplanet/ias/admin/common/ASException表示在运行时找不到ASException的定义。

    在应用服务器中运行时,该类由iPlanet Application Server提供,代码运行良好。要在应用程序服务器上下文之外运行此代码,您必须通过将其放入类路径来“手动”提供它。因此,您必须将正确的 iPlanet JAR 添加到类路径中(这是棘手的部分,您必须找到哪一个)。

    此外,我可以看到您正在使用InitialContext 非参数构造函数,因此您在应用程序服务器中运行时使用了 iPlanet 的环境设置。在 iPlanet 之外(例如,对于单元测试),您必须自己为 iPlanet 提供正确的 JNDI 属性。为此,您必须将jndi.properties 文件与(至少)初始上下文工厂和提供程序 URL 一起放在类路径中。像这样的:

    java.naming.factory.initial=...
    java.naming.provider.url=...
    

    检查您的 iPlanet 文档中的值。

    【讨论】:

      【解决方案2】:

      那么,当您调用测试时,com.iplanet.ias.admin.common.ASException 在类路径中吗?

      您是依靠应用服务器将 JDBC 驱动程序的库放在其类路径中,还是您自己部署它?

      【讨论】:

      • 我依赖应用服务器。因为 appserver 已经有了我只想编写测试并与之相处的所有设置。
      • com.iplanet 的东西似乎是 Sun App 服务器的管理属性。这可能需要从应用服务器获取 JDBC 资源。 ...但 Junit 测试并未在应用服务器上“部署”...
      • 但是如果您的单元测试调用代码尝试加载 JDBC 驱动程序,那么执行单元测试时 JDBC 驱动程序需要位于类路径中。
      【解决方案3】:

      我很好奇您为什么要编写服务定位器。它是任务的一部分吗?在现实世界中,依赖注入显然是更好的选择,使用 Guice 或 Spring。

      【讨论】:

      • 不,这不是一个任务。我们有仍在使用 JDBC 的旧代码(与 ORM 相比)。我正在尝试将这个遗留代码移动到更“真实世界”。您有任何关于弹簧注射的链接想要分享吗?
      猜你喜欢
      • 1970-01-01
      • 2011-09-22
      • 2018-01-19
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      相关资源
      最近更新 更多