如何模拟/存根/填充SerialPort.GetPortNames()

时间:2019-05-21 20:52:57

标签: c# unit-testing mocking serial-port shim

我正在尝试在C#中测试ApiController类,特别是使用SerialPort.GetPortNames()的函数。返回的内容取决于运行它的机器,所以我希望能够以某种方式对它进行Shim / stub / mock使其返回虚拟数据。

使用Visual Studio 2015,项目目标为.net 4.5.2,并使用Microsoft.VisualStudio.TestTools.UnitTesting

我认为Microsoft Fakes可以完全满足我的需要,但是我没有Visual Studio Enterprise。

我了解到Moq在这里毫无价值,并且pose无法与项目目标的.Net版本(4.5.2)一起使用。

我已经研究过prig,但是我不知道如何为datetime.now()之外的其他任何东西配置它。

我不知道如何使用Smock进行实际测试。

        [HttpGet]
        [Route("PortList")]
        public HttpResponseMessage SerialPortList()
        {
            HttpResponseMessage response;
            try
            {
                List<string> Ports = new List<string>(SerialPort.GetPortNames());
                response = Request.CreateResponse(HttpStatusCode.OK, Ports);
            }
            catch (Exception ex)
            {
                response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            }
            return response;
        }

我希望能够从SerialPort中填充(正确的单词?)静态方法,并使其返回串行端口([“ COM1”,“ COM2”])的虚拟列表。

1 个答案:

答案 0 :(得分:0)

我绕开模拟SerialPort.GetPortNames之类的静态方法的方法是添加一个间接层。在这种情况下,最简单的方法是创建一个SerialPortList重载,像这样接受Func<string[]>

public HttpResponseMessage SerialPortList()
{
    return SerialPortList(SerialPort.GetPortNames);
}

public HttpResponseMessage SerialPortList(Func<string[]> getPortNames)
{
    HttpResponseMessage response;
    try
    {
        List<string> Ports = new List<string>(getPortNames());
        response = Request.CreateResponse(HttpStatusCode.OK, Ports);
    }
    catch (Exception ex)
    {
        response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
    }
    return response;
}

在单元测试中...

public void Test()
{
    var portNames = new[] { "COM1" };
    foo.SerialPortList(() => portNames);
}