单元测试库的存在/不存在

时间:2010-10-05 09:50:59

标签: java unit-testing junit classpath classloader

问题:有没有办法可以使用ClassLoader测试我正在检查的库的存在和不存在?

我有一些代码可以使用特定的库(如果可用),或者如果没有则可以使用某些嵌入式代码。它工作正常,但我不知道如何在同一次运行中对两种情况进行单元测试,或者甚至可能。目前,我的单元测试只检查一个案例,因为库位于主类路径中,或者不是。

我用来检查库可用性的代码基本上是:

boolean available;
try {
  Class.forName("net.sf.ehcache.CacheManager");
  available = true;
} catch (ClassNotFoundException e) {
  available = false;
}

我可能会改变这种方式,如果它可以使单元测试更容易。

1 个答案:

答案 0 :(得分:1)

你试图一次做两件事:

  • 测试代码的不同实现,
  • 测试是否根据具体情况选择了正确的实施方式(或者更常见的是,无论相关库是否存在,您的应用程序都能正常运行)。

将两个任务分成不同的测试可以简化问题。因此,我将您的代码的两个版本实现为两个策略,并将检查类路径的代码放入Factory(方法)中创建必要的策略。然后,两个策略都可以独立于类加载器和类路径设置进行单元测试:

interface MyStrategy {
  public void doStuff();
}

class MyLibraryUsingStrategy implements MyStrategy {
  public void doStuff() {
    // call the library
  }
}

class MyEmbeddedStrategy implements MyStrategy {
  public void doStuff() {
    // embedded code
  }
}

在单元测试中,您可以简单地创建和测试任一具体策略:

@Test
void testEmbeddedStrategy() {
  MyStrategy strategy = new MyEmbeddedStrategy();
  strategy.doStuff();
  // assert results
}

创建适当策略的简单工厂方法:

MyStrategy createMyStrategy() {
  MyStrategy strategy;
  try {
    Class.forName("net.sf.ehcache.CacheManager");
    strategy = new MyLibraryUsingStrategy();
  } catch (ClassNotFoundException e) {
    strategy = new MyEmbeddedStrategy();
  }
  return strategy;
}

由于工厂代码相当简单,您甚至可能决定不为其编写自动化测试。但无论如何,测试工厂比集成测试更多(部分)集成测试;你可以简单地将你的应用程序的不同设置放在一起 - 一个与另一个没有相关的库 - 并看到它们都正常工作。