I'm trying to test an ApiController class in C#, specifically a function that uses SerialPort.GetPortNames(). what this returns depends on the machine it is run on, So I'd like to be able to Shim/stub/mock it in some way to have it return dummy data.
using visual studio 2015, project targets .net 4.5.2, and using Microsoft.VisualStudio.TestTools.UnitTesting
I think Microsoft Fakes would be able to do exactly what I need, but I do not have Visual Studio Enterprise.
I've learned that Moq is worthless here, and pose doesn't work with the version of .Net the project is targeting (4.5.2).
I've looked into prig, but I have no idea how to configure it for anything besides datetime.now().
and I don't understand how to actually test using 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;
}
I want to be able to shim (right word?) the static method from SerialPort, and have it return a dummy list of serial ports (["COM1","COM2"]).
The way I get around mocking static methods like SerialPort.GetPortNames
is to add a layer of indirection. The simplest way in your case is to create a SerialPortList
overload that accepts a Func<string[]>
like so.
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;
}
in your unit test...
public void Test()
{
var portNames = new[] { "COM1" };
foo.SerialPortList(() => portNames);
}