单元测试库是否存在

发布于 2024-09-26 03:09:47 字数 443 浏览 1 评论 0原文

问题:有没有办法使用ClassLoader来测试我正在检查的库是否存在?

我有一些代码将使用如果可用,则使用特定的库,如果没有,则回退到某些嵌入式代码。它工作正常,但我不确定如何在同一运行中对这两种情况进行单元测试,或者是否可能。目前,我的单元测试仅检查一种情况,因为该库要么位于主类路径中,要么不在主类路径中。

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

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

如果可以使单元测试更容易,我可能会改变完成此操作的方式。

The question: Is there a way I can use a ClassLoader to test both the presence and absence of the library I'm checking for?

I have a some code which will use a particular library if available, or fall back to some embedded code if not. It works fine but I'm not sure how to unit test both cases in the same run, or if it's even possible. At the moment, my unit tests only check one case because the library is either in the main classpath or it's not.

The code I use to check for the library availability is basically:

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

I could potentially alter the way this is done, if it would make unit testing easier.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖凝香 2024-10-03 03:09:47

您尝试同时做两件事:

  • 测试代码的不同实现,并
  • 测试是否根据情况选择了正确的实现(或者,更一般地说,无论相关库是否存在,您的应用程序都可以正常工作)展示)。

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

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;
}

由于工厂代码相当简单,您可以甚至决定不为其编写自动化测试。但无论如何,测试工厂更多地(部分)是集成测试而不是单元测试;您可以简单地将应用程序的不同设置放在一起 - 一个包含相关库,另一个不包含相关库 - 并查看两者是否正常工作。

You are trying to do two things at once:

  • test the different implementations of your code, and
  • test that the correct implementation is selected based on the circumstances (or, more generally, that your app works regardless of whether or not the library in question is present).

Separating the two tasks into distinct tests simplifies the problem. Thus, I would implement the two versions of your code as two Strategies, and put the code which checks the classpath and creates the necessary strategy into a Factory (Method). Then both strategies can be unit tested independent of classloader and classpath settings:

interface MyStrategy {
  public void doStuff();
}

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

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

In unit tests, you can simply create and test either of the concrete strategies:

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

A simple factory method to create the appropriate strategy:

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

Since the factory code is fairly trivial, you may even decide not to write automated tests for it. But at any rate, testing the factory is more (part) of an integration test than a unit test; you can simply put together different setups of your app - one with and the other without the library in question - and see that both work properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文