gpt4 book ai didi

c# - 如何通过实现接口(interface)来模拟TCPClient

转载 作者:太空宇宙 更新时间:2023-11-03 12:43:35 25 4
gpt4 key购买 nike

我是计算机科学的新手,对网络知识了解不多。我在实习期间接到了一个任务,就是通过实现接口(interface)来模拟一个TCPClient。这个想法是因为我们不需要连接到真实的服务器,我们只需要一个模拟的 TCPClient 来接收数据,保存并发送出去。据我了解,是否只是模拟TCPClient中的sendmessage函数??

public interface ITCPClient
{
/// <summary>
/// Event handler when TCP client is connected
/// </summary>
event ConnectionEventHandler Connected;

/// <summary>
/// Event handler for TCP Client on receiving data
/// </summary>
event DataReceivedEventHandler DataReceived;

/// <summary>
/// Event handler when TCP client is disconnect
/// </summary>
event ConnectionEventHandler Disconnected;

/// <summary>
/// Reports error when an error occurs
/// </summary>
event ErrorEventHandler OnError;

/// <summary>
/// Set whether to use HostByteOrder or NetworkByteorder with the socket - gateway expects network byte order
/// </summary>
bool ByteOrder { get; set; }

/// <summary>
/// Returns true if the client is running and connected to the server
/// </summary>
bool IsRunning { get; }

/// <summary>
/// Add the message to the sendqueue. The message will be processed by the ProcessMessage function waiting for the message.
/// </summary>
/// <param name="Message"></param>
void SendMessage(string Message);

/// <summary>
/// Add the message to the sendqueue. The message willbe processed by the ProcessMessage function waiting for the message.
/// </summary>
/// <param name="Message"></param>
void SendMessageHiPriority(string Message);

/// <summary>
/// Starts the client and spawn the thread for processing the message
/// </summary>
void Start();

/// <summary>
/// Disconnects and stops listening for messages
/// </summary>
void StopProcessing();

}

public class MockTCPClient : ITCPClient
{
#region Private Fields

private string msg;

#endregion Private Fields


#region Constructor

public MockTCPClient()
{
//nothing
}


#endregion Constructor

#region event

public event ConnectionEventHandler Connected;
public event ConnectionEventHandler Disconnected;
public event ErrorEventHandler OnError;
public event DataReceivedEventHandler DataReceived;

#endregion event

#region property
//question
public string ReceivedMessage
{
get
{
return msg;
}

set
{
msg = value;
}

}

#endregion property

//question??
private void OnDataReceived(object sender, string e)
{
DataReceivedEventHandler dataReceived = DataReceived;
if (dataReceived != null)
dataReceived(this, e);
}


#region ITCPClient Members
#region properties

public bool ByteOrder { get; set; }


public bool IsRunning { get; }

#endregion properties

public void SendMessage(string Message)
{
msg = Message;
}

public void SendMessageHiPriority(string Message)
{
}

public void Start()
{
}


public void StopProcessing()
{
}


#endregion ITCPClient Members

}

最佳答案

这演示了 Moq 如何验证您的类是否调用了它的方法之一。

这个测试
- 创建 ITCPClient 的模拟
- 指定 SendMessage 方法是可验证的 - 换句话说,它的使用将被跟踪。
- 验证是否已在模拟对象上调用了 SendMessage("test");

测试将失败,因为它从不调用 SendMessage("test");

[TestMethod]
public void TestTcpClient()
{
var mockedTcpClient = new Mock<ITCPClient>();
mockedTcpClient.Setup(x => x.SendMessage(It.IsAny<string>())).Verifiable();
//mockedTcpClient.Object.SendMessage("test");
mockedTcpClient.Verify(x=>x.SendMessage("test"));
}

如果我们取消注释调用 SendMessage("test") 的行,那么测试将通过。

因此在“实际”使用中,您将创建 Mock 并在测试依赖于它的类时使用它代替 ITCPClient。完成后,您可以验证您的类调用了 SendMessage 并传递了预期值。

如果您不能使用 Moq,这里有一个完全不同的方法:

创建一个实现 ITCPClient 的类,如下所示。您可以将大部分方法留空,只实现 SendMessage 以及其他一些细节:

public class TcpClientMock : ITCPClient
{
private readonly List<string> _sentMessages;

public TcpClientMock(List<string> sentMessages)
{
_sentMessages = sentMessages;
}

public void SendMessage(string Message)
{
_sentMessages.Add(Message);
}

//rest of non-implemented methods
}

在你的单元测试中,这样做:

var sentMessages = new List<string>();
var mockedTcpClient = new TcpClientMock(sentMessages);

然后创建您要测试的任何类并对其进行操作。完成后,查看 sentMessages 是否包含您期望的消息。


至于接收数据,我想您需要告诉您的模拟对象引发该事件,以便您可以验证您的类在事件引发时是否按预期响应。您可以像这样向 TcpClientMock 添加一个方法:

public void SimulateDataReceived(object sender, DataReceivedEventHandlerArgs args)
{
DataReceived(sender, args);
}

这样,当您设置了依赖于 ITCPClient 的类时,您可以在 mock 上调用 SimulateDataReceived,使其引发事件,这反过来又会让你的测试对象使用react。

关于c# - 如何通过实现接口(interface)来模拟TCPClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38110389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com