【问题标题】:How to write unit tests for classes which use hardware resources?如何为使用硬件资源的类编写单元测试?
【发布时间】:2017-05-08 22:00:21
【问题描述】:

我创建了一个从JSSC library 扩展的类,它使用低级通信方法(sendByte、sendString 等)。我想通过 JUnit 对其进行测试,但我不太知道该怎么做。

例如,我们看看下面的方法:

public void openConnection() throws SerialPortException {
  serialPort.openPort();
  configureConnectionParameters(serialPort);
  configureReadListener(serialPort);
}

为了确保方法正常工作,我需要一个实际的硬件设备来查看端口是否正确打开,并且在配置过程中没有抛出异常。但是在单元测试期间使用外部资源通常被认为是一种不好的做法,所以我开始想知道是否有解决此类问题的方法(可能是模拟硬件?)。

或者,我必须对它进行单元测试吗?

【问题讨论】:

  • 有一些模拟库就是为了这个目的。 jmockit.org 是我在工作中使用最多的一个;还有 Mockito、PowerMock。
  • 您应该考虑首先为 SerialPort、ISerialPort 创建一个接口,然后从您的单元测试程序中对其进行模拟,最后在测试时使用依赖注入将您的模拟注入到您的类中。
  • 感谢您的回复,但要么我不正确理解模拟机制,要么我真的不能在这里使用它。 openConnection 在自身内部使用 SerialPort 对象,所以我应该如何模拟它我不能修改测试方法,只能修改周围环境?
  • 您必须将它作为依赖项传递给您的类。请参阅我的答案中的示例。

标签: java testing hardware


【解决方案1】:

您可能应该更改类的结构并注入serialPort

通过这种方式,您可以在单元测试期间模拟注入的串行端口,并另外创建具有更少隐藏依赖项的更简洁的代码。

示例:

public class PortHandler {

    private final SerialPort serialPort;

    public PortHandler(SerialPort serialPort) {
      this.serialPort = serialPort;
    }

    [...]

    public void openConnection() throws SerialPortException {
      serialPort.openPort();
      configureConnectionParameters(serialPort);
      configureReadListener(serialPort);
    }

    [...]
}

@Test
public void testShouldOpenPortOnOpenConnection()
      throws Exception {

    SerialPort mockedPort = mock(SerialPort.class);
    PortHandler portHandler = new PortHandler(mockedPort);
    portHandler.openConnection();

    verify(mockedPort, times(1)).openPort();
}

资源:

  • 示例中使用的模拟框架:Mockito

【讨论】:

  • 我听说过 DI,但我一直认为它是针对大型应用程序的高度专业化设计原则。它既不复杂也不像我想的那么难。很好的答案,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 1970-01-01
  • 2010-11-03
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多