Reputation: 357
How shoud unit tests be written for a method that performs a send-recieve operation in orther to communicate with a generic device?
In the following example, in order to query a serial device (MyDevice.Read
method) a string formatted in a specific way is sent to the device and the device responds with a specific string according to the message sent.
This is the interface needed to mock the serial port:
public interface ISerialPort
{
void WriteLine(string text);
void ReadLine(string text);
}
This is the client class that uses the interface:
public class MyDevice
{
private ISerialPort _port;
public MyDevice(ISerialPort port)
{
_port = port;
}
public DeviceResponse Read(...)
{
_port.WriteLine(...);
string response = _port.ReadLine();
// Parse the response.
return new DeviceResponse(response);
}
}
And this are the unit tests for the Read method (failing/exception tests are left out on purpose) that I would write:
[TestClass]
public class MyDeviceTests
{
[TestMethod]
public void Read_CheckWriteLineIsCalledWithAppropriateString()
{
Mock<ISerialPort> port = new Mock<ISerialPort>();
MyDevice device = new MyDevice(port.Object);
device.Read(...);
port.Verify(p => p.WriteLine("SpecificString"));
}
[TestMethod]
public void Read_DeviceRespondsCorrectly()
{
Mock<ISerialPort> port = new Mock<ISerialPort>();
MyDevice device = new MyDevice(port.Object);
port.Setup(p => p.ReadLine()).Returns("SomeStringFromDevice");
DeviceResponse response = device.Read(...);
// Asserts here...
}
...
}
Another doubt: Is it correct to write a test just to check if a method should be called with specific arguments?
Upvotes: 2
Views: 658
Reputation: 30820
This is a good way to "unit test" such a device. Unless you want to connect a real device or simulated one.
You should keep each test simple and to the point - i.e. when testing read return the expected string (and nothing else) and check the system behavior, when writing verify that write was called with the exact string.
Upvotes: 1