我有一个基于 TCP 的客户端-服务器系统,用 C# 编码。我被要求添加双向心跳来发现网络中是否有任何元素卡住并且没有响应。
我通过从服务器向所有连接的客户端发送心跳并等待响应来解决了这个问题。如果响应未按时到达,则会出现超时;如果服务器在 2 秒内没有发送任何心跳(假设服务器被卡住),客户端也会出现超时。
一切都在内部发生,服务器和客户端都会公开任何事件(接收心跳、回复心跳,按照请求静默发生)
问题是..如何为这样的功能创建单元测试或集成测试?
注意:我在 Visual Studio、C#、.Net 4.6.1 中进行编码,使用 NUnit3 进行测试
简短的伪代码示例:
//we have one connector for each connected client
class connector{
//if the echoReceived timer is not reseted on time it will complain
Timer echoReceived = new Timer(200ms);
//Another timer for sending beats
Timer heartbeatSender = new Timer (1000ms);
OnClientConnected(Client)
{
echoReceived.elapsed += () => { ShowError("Client did not reply") };
heartbeatSender.elapsed += () => {
Send(client, new Message(Heartbeat));
echoReceived.Enabled = true;
});
heartbeatSemder.isEnabled = true;
}
OnNewMessageFromClient(Client, message)
{
if(message is echoedHeartBeat)
{
echoReceived.Enabled= false;
echoReceived.Reset();
}
}
}
在客户端
class client
{
Timer ServerDeadTimeOut = new Timer (1000ms);
OnStart()
{
serverDeadTimeOut.Elapsed += () => { ShowError("Server is dead"); };
serverDeadTimeOut.isEnabled = true;
}
OnNewMessageFromServer(message)
{
if(message is HeartBeatMessage)
{
serverDeadTimeOut.Reset();
Send(new HeartBeatEchoMessage);
}
}
}
最佳答案
我会选择单元测试,集成需要在两者之间建立某种连接,具体取决于实现,它可能更容易或更难。单元测试将简单地依赖于抽象。只需将接口(interface)注入(inject)连接器,并在单元测试中将它们替换为 Mock,以模拟您设计该类的场景。当然,您必须测试 Timer、Logger 和 ClientListener 的实际实现,但这就是单元测试的用途。
public class ConnectorTest
{
private readonly Connector _connector;
private readonly TimerMock _receiverMock;
private readonly TimerMock _senderMock;
private readonly LoggerMock _loggerMock;
private readonly ClientListenerMock _listenerMock;
public void Setup()
{
_listenerMock = new ClientListenerMock();
_receiverMock = new TimerMock();
_senderMock = new TimerMock();
_loggerMock = new LoggerMock();
_connector = new Connector(_listenerMock, _receiverMock, _senderMock, _loggerMock)
}
public void HeartbeatSender_ShouldBeEnabled_OnceClientIsConnected()
{
_listenerMock.SimulateClientConnection();
Assert.IsTrue(_senderMock.IsEnabled);
}
public void Error_ShouldBeLogged_WhenConnectedClientDidNotEchoed()
{
_listenerMock.SimulateClientConnection();
_receiverMock.SimulateEchoTimeout();
Assert.AreEqual("Client did not reply", _loggerMock.RecentErrorMessage);
}
}
关于c# - 单元测试心跳功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53334035/