如何为依赖于SerialPort的类编写单元测试?

时间:2009-05-12 06:27:19

标签: c# unit-testing mocking

我知道简短的回答是Mocks,但任何例子都会很好。我需要能够测试以下内容:

  1. 连接/断开
  2. 按设定的时间间隔接收数据
  3. 暂停数据传输,导致我的班级尝试重新连接
  4. 测试事件是否在预期时触发。
  5. 首先,我考虑定义一个接口,它将使用一个流,这将允许我简单地让我的类连接到任何流,我可以控制比串行端口更好,并允许我以程序化的方式做。如果有人有更好的想法,我会非常感激。

3 个答案:

答案 0 :(得分:3)

听起来你想进行集成测试而不是单元测试?

如果您的意思是单元测试,您可以:

  1. 围绕串口创建包装器
  2. 给包装器一个接口,也许是IPort
  3. 将此传递到需要SerialPort
  4. 的类中
  5. 模拟传入的SerialPost

  6. internal interface IPort
    {
       void Connect(); 
       //Other members
    }
    
    internal class SerialPort : IPort
    {
       public void Connect() 
       {
          //Implementation
       }
    }
    
    public class DataRetriever
    {
       private IPort _port;
       public DataRetriever(IPort port)
       {
           _port = port;
       }
    
       public void ReadData()
       {
          _port.Connect();
       }
    }
    

    现在您可以测试Data Retriever类。不幸的是,当您接近框架(例如SerialPort包装器)时,您无法对其进行单元测试。您需要将其留给集成测试。

答案 1 :(得分:2)

http://en.wikipedia.org/wiki/COM_port_redirector列出了一些免费/开源的虚拟COM端口驱动程序/重定向程序,这对您的测试很有帮助!

答案 2 :(得分:0)

我已成功使用以下内容,但仅用于测试数据处理和内部时序。这无法应对关闭/打开SerialPort本身的TestingClass。

        using (NamedPipeServerStream input = new NamedPipeServerStream("Test", PipeDirection.InOut))
        using (NamedPipeClientStream pipeClient = new NamedPipeClientStream("Test"))
        using (MemoryStream output = new MemoryStream())
        using (StreamReader inSerial = new StreamReader(pipeClient))
        using (StreamWriter outSerial = new StreamWriter(svpConsumer))
        {
            StartPipeServer(input);
            pipeClient.Connect();
            using (TestingClass myTest = new TestingClass(onSerial, outSerial))
            {
               input.Write(...);
               input.Flush(...);
               Assert on checking output
            }
        }

其中:

    internal void StartPipeServer(NamedPipeServerStream pipeServer)
    {
        Thread thread = new Thread(WaitForConnections);
        thread.Start(pipeServer);
    }

    internal void WaitForConnections(object o)
    {
        NamedPipeServerStream pipe = (NamedPipeServerStream)o;
        pipe.WaitForConnection();
    }

HTH,     RIP